Решил собрать в одном месте способы реализации каталога с большим количеством атрибутов товара (как на Яндекс.Маркете), их плюсы и минусы.
1. Один тип материала со всеми возможными полями
Создать один тип материала Товар, в который добавить все возможные поля. Категорию товара сделать полем таксономии. В форме товара показывать нужный набор полей с помощью своего аджаксового аналога Conditional Fields:
- Тип материала Товар
- Поле Категория
- Поле Диагональ
- Поле Операционная система
- Поле Мощность
- Поле Размер
- ...
Плюсы:
- Один тип материала. Легче создавать вьюхи, индексировать и т.п.
- Легко вводить данные (готовые виджеты)
- Относительно лёгкая темизация (уже готовые форматтеры)
- Возможно использовать multi-value атрибуты
- Относительно-простой способ создания поиска/фильтрации/фасетов (только в случае с заранее известным набором атрибутов)
- Относительно-лёгкое добавление новых категорий и полей (нужны знания админки и соответствующие права)
Минусы:
- Не подходит для реально большого числа атрибутов (больше нескольких десятков)
- Не подходит когда список атрибутов заранее неизвестен (например при парсинге или импорте)
- Много таблиц
field_data_*
иfield_revision_*
- Каждое поле — это дополнительный SQL запрос при отсутствующем кэше
- Тяжело добавлять зависимость поля от категории
2. Множество типов материала с разными наборами полей
Для каждой категории создать свой тип материала (или сущности product, если речь о Drupal Commerce) со своим набором полей.
- Тип материала Планшеты
- Поле Диагональ
- Поле Операционная система
- ...
- Тип материала Колонки
- Поле Мощность
- Поле Размер
- ...
Плюсы:
- Можно использовать одно поле в нескольких категориях (например поле "Вес" будет почти везде)
- Легко вводить данные (готовые виджеты)
- Относительно лёгкая темизация (уже готовые форматтеры)
- Возможно использоваться multi-value атрибуты
- Относительно-простой способ создания поиска/фильтрации/фасетов (только в случае с заранее известным набором атрибутов)
Минусы:
- Не подходит для реально большого числа атрибутов (больше нескольких десятков)
- Не подходит когда список атрибутов заранее неизвестен (например при парсинге или импорте)
- Много таблиц
field_data_*
иfield_revision_*
- Нет базового типа материалов, по которому можно строить Views, делать темизацию и т.п. (хотя здесь можно опираться на префикс бандла — например
product_
) - Тяжело добавлять новые категории — нужно создать тип материала, добавить поля, настроить форматтеры, настроить views и прочее
3. Свой тип сущности с множеством свойств в качестве атрибутов
Создать с помощью Entity API свой тип сущности product с множеством свойств. Каждое свойство (атрибут) — поле таблицы. Категорию товара сделать полем таксономии, как в первом способе:
- Сущность Товар
- Поле Категория
- Свойство Диагональ
- Свойство Операционная система
- Свойство Мощность
- Свойство Вес
- ...
Плюсы:
- Все данные в одной таблице
Минусы:
- Не подходит для реально большого числа атрибутов
- Не подходит когда список атрибутов заранее неизвестен (например при парсинге или импорте)
- Кодинг
- Относительно-сложно вводить данные (нет виджетов)
- Сложная темизация (нет форматтеров)
- Тяжёлое добавление новых полей (изменить схему бд, добавить виджет в форму, вывести значение)
- Невозможно использовать multi-value атрибуты, придётся делать их полями или кодить логику вручную
- Придётся помучаться с поиском/фильтрацией
4. Составное multi-value поле из двух полей — атрибут, значение (EAV)
Добавить к типу материала составное multi-value поле Атрибуты, в котором можно будет выбрать атрибут и ввести его значение:
Такой способ называется EAV (Entity–attribute–value) и используется в OpenCart и многих других CMS.
Название атрибута может быть как термином таксономии, так и просто строкой.
Поле можно написать либо самому, либо воспользоваться такими модулями как Field collection, Multifield, Double field. Для Drupal 8 можно использовать мой модуль EAV Field.
Плюсы:
- Подходит для большого числа атрибутов
- Подходит когда список атрибутов заранее неизвестен
- Все данные в одной таблице
- Условно-возможно использовать multi-value атрибуты (просто один атрибут будет указан несколько раз)
- Относительно-лёгкое добавление новых категорий
Минусы:
- Кодинг
- Все значения атрибутов будут одного типа — строки. Хотя можно придумать костыли.
- Относительно-сложно вводить данные (нет виджетов)
- Относительно-сложно темизировать (нет форматтеров)
- Сложно реализовать поиск/фильтрацию по атрибутам
Выводы: если атрибутов не очень много (несколько десятков), то можно воспользоваться первым способом, если до сотни — то вторым, если атрибутов много или они заранее неизвестны, то четвёртым.
Кто сталкивался с подобной задачей, напишите свой способ решения.
Комментарии
Пользовался вторым вариантом, но эт то-же мрак. Неподготовленному пользователю не доверишь добавление новых типов. И очень сложно добавлять все свойства. Особенно когда для разных типов товаров свойство называется одинаково а параметры разные.
Если ревизии не нужны то можно удалить лишние таблицы
https://www.drupal.org/project/field_sql_norevisions
Пользовал 2, 3 и к 4му добавил бы https://www.drupal.org/project/properties (грабли с импортом)
кодить приходится везде, ибо логика везде своя
У вас есть реальные примеры чего-то похожего на Маркет Яндекса, где работал бы какой-то из перечисленных вариантов? Когда сотни типов товаров и у каждого порядка сотни характеристик, по которым будет идти фильтрация.
Думаю что для реализации подобного придется придумать вариант 5.
http://www.ktc-ua.com/
работает на втором способе
Извини, что наглею, но если поиск с фасетами прикручивать то какой вариант лучше с точки зрения производительности. И с точки зрения кеширования, какой вариант лучше?
фасеты из коробки будут работать только с первым и вторым способом
Пользуюсь способами 1, 2.
Остальные способы, как на меня, имеют недостатки которые перекрывают все "+":
То есть, если много полей в товаре, и разработчик пользуется способом 3, 4 - придется много кодить и решать выше перечисленые проблемы.
Тогда возникает вопрос о целесообразности использования самого Друпала, как инструмента, для создания оного каталога / магазина.
Для меня идеальным "рецептом" является способ 1 и 2 + продвинутое кеширование.
Как правило на больших сайтах ничего не правят вручную, всё импортируется из внешнего источника, поэтому виджеты не так важны. Ну а заставить search api индексить данные из составного поля я думаю как-то можно, после этого и фасеты сами заработают.
Скажи, пожалуйста, как вы сделали на указанном вами сайте КТС, чтобы в поиске при вводе части слова выскакивало не только описание возможного товара но и картинка?
Спасибо.
это не я делал
У меня такое на шестерке реализовано вот тут http://podshipnik-servis.ru
Тип материала Товар, 40 общих полей для всех товаров.
Самописный модуль клонирования типов материалов. Когда надо, клонирую тип Товар и добиваю новыми полями и группами. Точнее, это манагеры делают.
Сделано несколько шаблонных Views по полям типа Товар.
Самописный модуль клонирования Views, которому можно указать тип товара и он добавит оттуда все дополнительные для данного товара поля во вьшку и раскрытые фильтры к ней.
Так и живем уже три года. :)
Перепробовал все способы, пришлось придумать свой. Т.к. сайт не только каталог, но и магазин, то был взят за основу комерс, сразу с со своим энтити product. На каждую категорию товаров создавался свой тип продукта со своими полями. У редакторов есть возможность создавать поля самим. Так же поля переиспользовать в других типах.
Это дает возможность использовать выборки по парент ноде и везде единообразно работать с нодой produc_display.
Дальше идет магия.
Словарь таксономии - каталог содержит в себе спец поле - тип продукта, в котором указывается какой тип продукта будет тут отображаться, используется в форме редактирования: при выборе термина сразу автоматом грузится форма продукта с нужным типом. А во вторых используется при выводе: при отображении этого термина можно получить все поля продукта и построить фильтры.
Фильтры работают на СерчАпи.
При редактировании термина таксономии выбираем тип продукта, тут же сразу отображаются все поля продукта и появляется возможноть выбрать тип виджета и фильтра в каталоге, его порядок и группу. Если выбран фильтр то автоматом создается индекс в поиске.
Ну и естественно кастомный функционал отображения, который учитывает все ранее введенное.
К сожалению, так и не придумал как это все сделать контрибовским модулем, т.к. слишком много зависимостей от требуемого функционала. Пример работы можно посмотреть здесь http://karcher.com.by/minimoyki
Пока реализовано 4 сайта на этом движке. Пока полет нормальный. Буду надеятся что найдется время перевести этот функционал в контриб.
Я написал кастомный модуль наподобие field_collection с той лишь разницей, что можно налету переключать пресеты полей. Подробнее:
- Новая сущность fieldset (по типу продукта в екомерс)
- к сущности можно добавляем полями любые нужные атрибуты
- Так же модуль предоставляет кастомное поле, которые привызывает наборы полей к ноде.
Работает это так:
- Создаём тип ноды "товар" с общими полями (категория, цена, фотки, пр..)
- добавляем наше хитрое поле к ноде
При создании ноды:
- В кастомном поле выбираем заранее созданий нами пресет полей
- сохраняем
- на странице ноды появяется вкладка (либо ссылка), которая открываем форму атрибутов.
- если в ноде потом при редактировании переключить пресет, то данные из старого пресета удаляются.
В итоге что-то среднее между первым и вторым способом.
@Артур а с поиском/фильтрацией как?
В планах есть задумка продумать модуль по действительно неограниченому кол-ву атрибутов (строки, списки, числа, диапазоны) и не плодить таблицы.
Как основная идея хранить всё в одном текстовом биг-поле в формате html таблицы. Реализовать форматтары для вывода и ввода данных - что не так сложно.
Почему html таблица: потому что структурированное хранение, доступный по умолчанию просмотр и хорошая дефолтная индексация.
Ещё не продумал как полноценно подружить с вьюсом: фильтрация и сортировка, главным образом останавливает(с выводом полей проблем нет). Пока единственная идея делать индексные таблицы, но.. и это меня пока останавливает :))
xandeadx, по сколько эту полноценные сущности и вообще друпал-вей, то я добавил поддержку вьюса для releationships - работает отлично.
Ну по сути точно такая же схема работает в drupal commerce - один product display и множество типов product со своими полями. Вариация второго способа.
xandeadx, по сути да, только у меня этот функционал можно ещё цеплять к разным типам нод.
У меня на сайте 3 каталога: Модели оборудования, Аксессуары, Расходные материалы.
У них разные "общие свойства", разный набор доступных пресетов и разный дизайн :)
На самом деле мне просто жутко не хотелось разбираться в екомерс с учётом того что стандартные его сценарии не устраивали.
пример рабочего каталога (здесь без фильтров, с фильтрами другой сайт в работе)
http://ergomax-rf.ru/equipment/1
Кстати, спасибо за помощь с модулем яндекс карт (я его на этот сайт и ставил)
Использую второй способ, но с небольшим хаком. Я создал сущность типа product и сделал кодингом реализацию наследования, т.е. у меня в типе product референс ссылка на "материал товара". Мне это понадобилось вот зачем, во первых в сущность product я сваливаю поля, которые не нужны оператору, работающему с самим товаром, например: артикул (генерится автоматически), термины таксономии (присваиваются автоматически на основании значений полей), различные цены (от поставщиков они вводятся в валюте, а тут пересчитываются в рубли по курсу) и т.д. Также отпадает вышеописанная проблема вывода в вьюхах, не нужно фильтровать бандлы, можно создать обязательную бэк-зависимость от product.
В дополнение скажу, что сам не использую вьюхи напрямую, использую поиск Solr и фасеты, гораздо удобнее всё пропустить через поисковой движок и пользоваться уже так сказать простыми поисковыми оттисками от сложных товаров с множеством полей.
Проблему множества типов товаров не решал, у меня их порядка 10, полей порядка 20 у каждого.
Делал так:
1. Field Collection состоящий из двух полей: "key" и "value" - оба поля термины таксономии
2. Написал импорт с помощью Feeds - несуществующие параметры создаются автоматически
3. Написал индексацию данных параметров Search Api
4. Написал свой форматер для формирования урлов :)
как это работает? вкратце
Костылем :)
При включении добавляет новый фильтр, который в свою очередь добавляет все поля из словаря "Params key" в поля для индексации.
Потом просто отмечаешь необходимые - индексируешь, и создаешь фасеты.
Вариант с текстовыми полями пробовал - не подошел по причине невозможности сделать красивые урлы.
действительно костыльно :)
По сути это реализация моего комментария. Если атрибутов будет не сильно много (условно до сотни) то можно написать админку управления атрибутами (название, тип, вес и т.д.) и скрыть под капотом процесс добавления атрибута в индекс, создания фасета, вывода блока. Должно получится покрасивее.
Сейчас они и добавляются автоматом... Но вывод блока лучше таки вручную делать, т.к. при импорте разные косяки бывают ))
P.s. Не по теме, но отпишусь: совсем недавно стал использовать
Panels + Omega + Panels Everywhere
Очень рекомендую :) Сам три года не хотел их ставить, но сейчас могу сказать, что одни только плюсы.
Для 1 варианта как лучше или проще сделать фильтрацию по полям, чтобы для каждого типа товара выходили свои фильтры?
Попробовал модуль Views dependent filters вместе с Better Exposed Filters, не работает, дает ошибку, что еще можно попробовать? Или делать разные вьюшки для разных типов товара?
1. По факту работал с магазином в котором тысячи товаров и сотни атрибутов. Все это было в одно типе товара. В итоге имеем сотни джоинов, которые убивают сайт.
2. Вариант когда множество типов товаров, но ограниченное число атрибутов. Причем все значения атрибутов заталкиваются в несколько словарей. В итоге разросшийся словарь таксономии, который съедает всю php память, т.к. все tids заталкиваются в allowed values поля. Думаю что если поля будут текстовые, то проблема с производительностью вылезет позже. Есть сайт, где множество типов товаров и множество атрибутов. Т.к. они текстовые, то проседает не так сильно. Вопрос с фасетными фильтрами решается своим велосипедом.
3. Вот теперь смотрю на 4 вариант и думаю какие сюрпризы он может преподнести кроме очевидного (велосипед для фасетных фильтров).
Первый и второй вариант работали с автосозданием полей и типов материалов.
P.s.
В статье не хватает тэга commerce, чтобы можно было ее найти.
Смешанный способ:
Все как в 4, но помещается это втип поля с типом ссылка на сущность от модуля Inline Entity Form (описано Orion76 на drupal.ru).
(Хотя не знаю, может это и свопадает с чем-то что уже раньше описано)
Может немного не про то, но все же. Добавляем поле «Особенности» - ссылка на термин, добавляем все возможные особенности товара. Далее, для каждой категориии товара создаём свой Views с собственными фильтрами. С помощью BEF можно сделать чекбокмы для раскрытых фильтров. На небольшом количестве товаров и небольшом количестве параметров, работает «на ура»)
у "особенности" должно быть какое-то значение, как его вводить и где его хранить?
Теперь понял) В моем варианте любая «Особенность» будет иметь только значения «есть» или «нет».
Дорогой, Xandeadx, что-то изменилось с тех времён и перехода на Drupal 8-9?
Если да - могли бы Вы поделиться своими методами работы, особенно в связке много типов товаров с большим количеством полей характеристик, фасетным поиском по ним и импортом через feeds?
Ничего не изменилось. Готовых решений нет.
Добавить комментарий