Фасетный поиск. Фасетный поиск: улучшаем работу каталога товаров. Фасетная навигация: определение

  • 23.06.2020

Умный фильтр или Фасетный поиск – это фильтр по категориям товара, которую можно видеть в крупных интернет магазинах и том же яндекс.маркете. Он помогает последовательно сортировать товары с нужными пользователю свойствами, отсеявая все лишнее. Это очень удобная опция, позволяющая быстро найти нужный товар или материал на сайте.

И так давайте перейдем непосредственно к установке и настройке нужных нам модулей

Для начала нам понадобятся скачать и установить следующие модули: Search API , Search API Database Search , Entity API и Views .

На странице модулей включаем:

  • Search API
  • Search views
  • Database search
  • Entity API
  • Views
  • Views UI
  • Ctools
Создание поискового сервера

Идем в Конфигурация > Поиск и метаданные > Search API (/admin/config/search/search_api) и нажимаем Добавить сервер .
Затем вводим имя сервера, в выпадающем списке Класс сервиса (Service class) выбираем Database service и сохраняем.

Создание индекса

Идем в Конфигурация > Поиск и метаданные > Search API (/admin/config/search/search_api), жмем Добавить сервер (Add index) .
Вводим название индекса, в поле Тип элемента (Item type) выбираем ‘Материал ‘, в поле Сервер выбираем Database server , жмем Создание индекс.


В открывшейся форме отмечаем галочками поля, по которым будет производится сортировка, и сохраняемся.
Чтобы можно было делать сортировку по названию ноды, включаем title и напротив него в выпадающем списке выбираем тип string , а не fulltext . По fulltext сортировку делать нельзя.

В следующей открывшейся форме Фильтры (workflow) я оставил все по умолчанию, переходим на вкладку Просмотр (Status ), и нажимаем Индексировать сейчас (Index Now ).
После завершения индексации, создадим страницу поиска.

Создание страницы поиска

Идем в Structure > Views и жмем Добавить новое представление (Add new view) .
В новом представление в выпадающем списке Показать (Show) выбираем ранее созданный нами индекс, остальные поля (название, title и путь) заполняете так как вам нужно.


Далее нажимаем Сохранить и настроить (Continue & edit), настраиваем представление как обычно. В критериях фильтрации я добавил показ только опубликованных материалов и нужный тип node и настроил отображение необходимых полей (нужно добавить эти поля в индекс, чтобы иметь возможность фильтровать по ним).

На данном этапе с настройкой представления мы закончили, теперь перейдем непосредственно к фасетному фильтру.

A/search_api_ranges.module +++ b/search_api_ranges.module @@ -144,11 +144,8 @@ function search_api_ranges_minmax($variables, $order = "ASC") { // otherwise our min/max would always equal user input. $filters = &$query->getFilter()->getFilters(); foreach ($filters as $key => $filter) { - - // Check for array: old style filters are objects which we can skip. - if (is_array($filter)) { - if ($filter == $variables["range_field"] || ($filter != $variables["range_field"] && $filter == "")) { - $current_filter = $filters[$key]; + if(isset($filter->tags) && is_array($filter->tags)){ + if(in_array("facet:".$variables["range_field"], $filter->tags)){ unset($filters[$key]); } }

Патчим JQuery UI Slider: настраиваем редирект

В версии модуля 7х-1.5 я столкнулся с тем, что если виджет слайдера расположен на странице, отличной от страницы поиска, то после изменения диапазона цены проиходило пере направление на текущую страницу, а не на страницу поиска.
Ошибка кроется в функии search_api_ranges_block_slider_view_form_submit() (файл search_api_ranges.module, строка 364).
Я не стал особо разбираться, что там и зачем, просто немного изменил код в строке 427:

Drupal_goto($path, array("query" => array($params), "language" => $language)); + drupal_goto($values["path"], array("query" => array($params), "language" => $language));

после чего проблема решилась.

В данной статье (уровень веб-мастера - продвинутый) речь пойдёт о, пересекающейся по разным признакам, т.н. "фасетной" навигации. Для упрощения усвоения материала рекомендую пробежаться по статье в Википедии "Фасетная классификация " и публикации на английском языке (но с картинками!) "Design better faceted navigation for your websites ".

Фасетная навигация с фильтрацией по цвету или ценовому диапазону может быть полезна для ваших посетителей, но зачастую вредит в поиске из-за того, что создаёт множество комбинаций адресов с дублирующимся контентом . Из-за дублей поисковые системы не смогут быстро сканировать сайт на предмет обновлений контента, что соответственно влияет и на индексацию. Чтобы минимизировать эту проблему и помочь веб-мастерам сделать фасетную навигацию дружелюбной в отношении поиска, мы бы хотели:

Идеально для пользователей и поиска Google

Чёткий путь к продуктам/страницам статьи:

Представление URL для страницы категории:
http://www.example.com/category.php?category=gummy-candies

Представление URL для конкретного продукта:
http://www.example.com/product.php?item=swedish-fish

Нежелательные дубликаты, вызванные фасетной навигацией

Одна и та же страница доступна с различных веб-адресов:

Каноническая страница



URL: example.com/product.php? item=swedish-fish

Дублированная страница



URL:example.com/product.php? item=swedish-fish&category=gummy-candies&price=5-10


category=gummy-candies&taste=sour&price=5-10

Ошибки:

  • Бессмысленно для Google, так как пользователи редко ищут [мармелад по цене 9:55 долларов].
  • Бессмысленно для поисковых роботов, которые обнаружат один и тот же элемент ("фруктовый салат") от родительских страниц категорий (либо "Жевательный мармелад" или "кислый Жевательный мармелад").
  • Отрицательный момент для владельца сайта, потому запросы на индексацию разбавляются многочисленными версиями одной и той же категории.
  • Отрицательный момент для владельца сайта, потому что это бесполезная и лишняя нагрузка в пропускной способности сайта
Пустые страницы:


URL: example.com/category.php? category=gummy-candies&taste=sour&price=over-10

Ошибки:

  • Неправильно отдаётся код для поисковых систем (в таком случае страница должна отдавать код 404)
  • Пустая страница для пользователей


Наихудшие решения (не дружелюбные в отношении поиска) фасетной навигации

Пример №1 : В составе URL применяются не стандартные параметры: запятые и скобки, вместо ключ=значение& :

  • example.com/category? [ category:gummy-candy ][ sort:price-low-to-high ][ sid:789 ]
  • example.com/category?category , gummy-candy , sort , lowtohigh , sid , 789
Как надо:
example.com/category?category=gummy-candy&sort=low-to-high&sid=789

Пример №2 : Использование каталогов или путей к файлам, а не параметров в списках значений, которые не изменяют содержание страницы:
example.com/c123 /s789/ product?swedish-fish
(где /c123/ категория, /s789/ ID сессии, что не изменяет содержимое страницы)

Хорошее решение:

  • example.com /gummy-candy/ product?item=swedish-fish&sid=789 (каталог, /gummy-candy/, меняет содержимое страницы в значимым образом)
Лучшее решение:
  • example.com/product?item=swedish-fish&category=gummy-candy&sid=789 (параметры URL дают большую гибкость для поисковых систем, чтобы определить, как эффективно сканировать)
Поисковым роботам трудно дифференцировать полезные значения (например, "gummy-candy") от бесполезных (например, "SESSIONID"), когда эти значения помещаются непосредственно в пути ссылки. С другой стороны, параметры URL обеспечивают гибкость для поисковых систем, чтобы быстро проверить и определить, когда данное значение не требует доступ сканирующего робота (краулера) ко всем всем вариантам.

Общие значения, которые не меняют содержимое страницы и должны быть перечислены в качестве параметров URL, включают:

  • ID сессии
  • Отслеживание идентификаторов
  • Referrer идентификаторы
  • Отметки времени
Пример №3 : Преобразование созданных пользователями значений (возможно бесконечных) в параметры URL, которые доступны для сканирования и индексирования, но бесполезны для поиска.
Использование незначительных данных, генерируемых пользователями сайта (например, как долгота/широта или "дней назад"), в сканируемых и индексируемых адресах:
  • example.com/find-a-doctor? radius=15&latitude=40.7565068&longitude=-73.9668408
  • example.com/article?category=health& days-ago=7
Как надо:
  • example.com/find-a-doctor?city=san-francisco&neighborhood=soma
  • example.com/articles?category=health&date=january-10-2014
Вместо того, чтобы позволить пользователем генерировать значения для создания сканируемых URL-адресов (что приводит к бесконечным возможностям с очень небольшой ценностью для посетителей), лучше публиковать категорию страницы для наиболее популярных значений, вдобавок можно включать дополнительную информацию, чтобы страница представляла большую ценность, чем обычная поисковая cтраница с результатами. Кроме того, можно подумать о размещении сгенерированных пользователем значениях в отдельном каталоге, а затем через robots.txt запретить сканирование из этого каталога.
  • example.com/filtering/ find-a-doctor?radius=15&latitude=40.7565068&longitude=-73.9668408
  • example.com/filtering/ articles?category=health&days-ago=7
И в robots.txt:
User-agent: *
Disallow: /filtering/

Пример №4 . Добавление параметров URL без логики.

  • example.com/gummy-candy/lollipops/gummy-candy/ gummy-candy/product?swedish-fish
  • example.com/product?cat=gummy-candy&cat=lollipops&cat=gummy-candy &cat=gummy-candy&item=swedish-fish
Хорошее решение:
  • example.com /gummy-candy/ product?item=swedish-fish
Лучшее решение:
  • example.com/product?item=swedish-fish&category=gummy-candy
Посторонние параметры URL только увеличивают дублирование, в результате сайт менее эффективно сканируется и индексируется. Поэтому необходимо избавляться от ненужных параметров URL и периодически заниматься уборкой мусорных ссылок перед генерацией новых URL. Если многие параметры необходимы для пользовательского сеанса, можно скрыть информацию в куки, а не постоянно добавлять значения, как cat=gummy-candy&cat=lollipops&cat=gummy-candy& ...

Пример №5 : Предлагать дальнейшие уточнения (фильтрация), когда есть нулевые результаты.

Плохо:
Разрешать пользователям выбрать фильтры, когда существуют нулевые элементы для уточнения.


Уточнение к странице с нулевыми результатами (например, price=over-10), что расстраивает пользователей и вызывает ненужные запросы для поисковых систем.

Как надо:
Создавать ссылки только тогда, когда есть элементы для выбора пользователем. При нулевом результате ссылку помечать "серой" (т.е. недоступной для клика). Для дальнейшего улучшения юзабилити рассмотреть вопрос о включении показателя количества доступных элементов рядом с каждым фильтром.


Вывод страницы с нулевыми результатами (например, price=over-10) не допускается, плюс запрещается пользователям делать ненужные клики, а поисковым система сканировать эту не полезную страницу.

Необходимо предотвращать появление ненужных адресов и минимизировать пространство для посетителя, создавая URL только при наличии продукции. Это поможет пользователям оставаться занятыми на вашем сайте (меньше кликов по кнопке назад, когда не находится ни одного товара), уменьшит число возможных URL, известных поисковым системам. Кроме того, если страница не просто "временно нет в наличии", а вряд ли когда-нибудь будет содержать релевантную информацию, стоит рассмотреть возможность сделать для неё код ответа 404 . На 404-ой странице вы можете оформить полезное сообщение для пользователей с большим количеством опций в навигации или окно поиска, чтобы пользователи могли найти родственные продукты.

Для новых сайтов, веб-мастера которых рассматривают внедрение фасетной навигации, есть несколько вариантов оптимизации сканирования (совокупность адресов на вашем сайте, известных роботу Google) уникальных страниц контента и уменьшения попадания в индекс поисковой системы дублирующихся страниц (консолидация сигналов индексации).

Определите, какие параметры URL требуются для поисковых систем, чтобы сканировать каждую индивидуальный страницу с контентом (то есть, определить, какие параметры необходимы для создания, по меньшей мере одного клик-пути к каждому пункту). Обязательные параметры могут включать в себя item-id , category-id , page т.д.

Определите, какие параметры будут полезны для посетителей с их запросами, и какие скорее всего только вызовут дублирование при сканировании и индексировании. В примере с кондитерскими товарами (мармелад) параметр URL "taste " может быть ценным для пользователей с запросами в примере taste=sour . Тем не менее, логично посчитать параметр "price" вызывающим лишнее дублирование category=gummy-candies&taste=sour&price=over-10 . Другие распространенные примеры:

  • Ценные параметры для поисковиков: item-id , category-id , name , brand ...
  • Ненужные параметры: session-id , price-range ...
Рассмотрим реализацию одного из нескольких вариантов конфигурации для URL-адресов, которые содержат ненужные параметры. Просто убедитесь, что "ненужные" параметры URL действительно не требуются для сканирования поисковым роботам или для нахождения пользователем каждого отдельного продукта!

Вариант 1: и внутренние ссылки

Пометьте все ненужные URL-адреса атрибутом . Это уменьшит трудозатраты поискового робота и предотвратит снижение частоты сканирования. Глобально управлять сканированием нужно через robots.txt (Примеч. переводчика: см. статью " ").
Воспользуйтесь атрибутом rel="canonical", чтобы отделить страницы для поискового индекса от страниц, не нужных там (например на странице price=5-10 можно прописать атрибут rel="canonical", указывающий на категорию всего кислого мармелада example.com/category.php?category=gummy-candies&taste=sour& page=all ).

Вариант 2: Robots.txt и Disallow

URL-ы с ненужными параметрами включают в директорию /filtering/ , которая будет закрыта в robots.txt (запрет disallow). Это даст всем поисковым системам сканировать только "правильное" внутриссылочное (содержимое) сайта, но будет блокировать разом сканирование нежелательных URL. Например (example.com/category.php?category=gummy-candies ), если ценными параметрами были item, category и taste, и лишними были идентификатор сеанса и price, то URL будет для taste таким:
example.com/category.php?category=gummy-candies&taste=sour , но все ненужные параметры, такие как price, URL включит в предопределенный каталог - /filtering/:
example.com/filtering/ category.php?category=gummy-candies&price=5-10 ,
который затем через robots.txt будет запрещен:
User-agent: *
Disallow: /filtering/

Вариант 3: Раздельные хосты

Убедитесь, что лучшие решения, перечисленные выше (например, для ненужных адресов) все еще применяются. В противном случае поисковые системы уже сформировали большую ссылочную массу в индексе. Таким образом, ваша работа будет направлена ​​на снижение дальнейшего роста ненужных страниц, просмотренных с помощью робота Google и консолидацию сигналов индексации.

Используйте параметры со стандартной кодировкой и форматом ключ=значение (key=value).

Убедитесь, что значения, которые не меняют содержимое страницы, такие как идентификаторы сеансов, реализованы в виде ключ=значение, а не каталогов.

Не позволяйте кликать и не генерируйте URL-адреса, когда не существует элементов для фильтра.

Добавьте логику в отображение параметров URL: удалите ненужные параметры, а не добавляйте постоянно значения (например, избегайте такой генерации ссылки: example.com/product?cat=gummy-candy&cat=lollipops &cat=gummy-candy&item=swedish-fish ).

Сохраняйте ценные параметры в URL, перечислив их в первую (так как URL видны в результатах поиска) очередь и менее уместные параметры в последнюю (например, идентификатор сессии).
Избегайте подобной структуры ссылок: example.com/category.php?session-id=123&tracking-id=456 &category=gummy-candies&taste=sour
Настройте параметры URL в Инструментах для веб-мастеров, если имеете чёткое представление о работе ссылок на вашем сайте.

Убедитесь, что при использовании JavaScript для динамического управления контентом (sort/filter/hide) без обновления URL, есть реальные веб-адреса на вашем сайте, имеющие ценность в поиске, например, это основные категории и страницы продуктов, которые доступны для сканирования и индексирования. Старайтесь не использовать только домашнюю страницу (т.е. один URL) для всего вашего сайта, а через JavaScript динамически изменять контент навигацией - это, к сожалению, выдаст в поиске пользователям только один URL. Кроме того, проверьте, чтобы производительность не повлияла на работу динамической фильтрации в худшую сторону, так как помешает пользователю работать с сайтом.

Улучшите индексацию различных страниц одного контента указанием атрибута rel="canonical" на привилегированную версию страницы. Атрибут rel="canonical" может быть использован внутри одного и нескольких доменов.

Оптимизируйте индексацию контента, разбитого на страницы "паджинации" (например, page=1 и page=2 из категории "gummy candies") посредством (либо):

  • Добавьте атрибут rel="canonical" в серию страниц с указанием канонической категории с параметром “view-all” (например, page=1, page=2, и page=3 из категории "gummy candies" с with rel=”canonical” на category=gummy-candies&page=all ), удостоверившись, что страница необходима пользователям и загружается быстро.
  • Используйте разметку разбиения на страницы rel="next" и rel="prev" , чтобы указать на связь между отдельными страницами (см. статью "Paginaton with rel="next" and rel="prev" ") .
Включите только канонические ссылки в файлы Sitemap .

В сегодняшнем уроке мы с вами попробуем воссоздать имитацию фасетного (фасеточного) поиска средствами Javascript. Я подразумеваю, что вы уже знаете что такое фасетный поиск, раз читаете данный туториал, в противном случае погуглите или загляните на Amazon или мою Демку .

Для начала нам понадобится библиотека github.com/eikes/facetedsearch. Скачайте её и подключите файл facetedsearch.js к нашему проекту. Так же нам понадобятся библиотеки jQuery и Underscore.

Дисклеймер: Я понимаю, что JQ уже давно не торт, но использую его как привычный синтаксический сахар, вы можете перепилить это под более привычные вам библиоетки или на ванильном JS.

Итак для начала сделаем простенькую разметку с подключенными зависимостями:

Document // Сюда мы выведем фасетные фильтры // А тут будут наши элементы

Теперь нам нужно описать настройки нашего приложения и создать шаблон вывода элементов массива которые мы будем сортировать при помощи фасетов:

$(function(){ var item_template = // Описывем шаблон "" + "" class="img-responsive">" + ", " + "

" + "" + ", " + ", " + "

" + "

" + ""; settings = { items: example_items, facets: { // Указывем категории фасетов "category" : "What Category", "continent" : "Which Continent", "language" : "Programming Language" }, resultSelector: "#results", // DOM элемент куда мы выводим результаты facetSelector: "#facets", // DOM элемент для фасетов resultTemplate: item_template, paginationCount: 8, // Колличество элементов на страницу orderByOptions: {"firstname": "First name", "lastname": "Last name", "category": "Category", "RANDOM": "Random"}, facetSortOption: {"continent": ["North America", "South America"]} } $.facetelize(settings); });

Ну и собственно создать сам JSON массив с элементами для отображения в нашем фасетном поиске на JS:

Var items = [ { "firstname": "Mary", "lastname": "Smith", "imageURL": "http://lorempixel.com/150/150/cats/2", "description": "Sed Ea Amet. Stet Voluptua. Nonumy Magna Takimata ", "category": "Mouse", "language": ["Smalltalk", "XSLT"], "continent": "Africa" }, { "firstname": "Patricia", "lastname": "Johnson", "imageURL": "http://lorempixel.com/150/150/cats/3", "description": "Ut Takimata Sit Aliquyam Labore Aliquyam Sit Sit Lorem Amet. Ipsum Rebum. ", "category": "Lion", "continent": "North America" }, ... ];

Данный массив я бы вынес в отдельный JS файл который бы формировался динамически, из БД например.

Вот собственно и всё, мы получаем фасетный поиск на JavaScript и можем его кастомизировать. Далее я привожу переведённую документации библиотеки, где вы можете подсмотреть необходимые вам триггеры.

Документация Функции

Две функции экспортируются в пространство имен jQuery.

facetelize Используется для инициализации фасетного поиска с заданными настройками.

facetUpdate Может использоваться, если вы хотите изменить состояние фасетного поиска извне.

Настройки объектов

items: Массив элементов, которые будут отфильтрованы и отсортированы в процессе.

facets: Объект, для которого ключи соответствуют ключам элементов и значениям, является заголовком для этого фасета. Элементы будут отфильтрованы на основе того, какое значение они имеют для этих ключей.

orderByOptions: Подобно фасетам, за исключением того, что эти пары «ключ-значение» используются только для сортировки. Когда ключ RANDOM включен, результаты могут быть рандомизированы.

facetSelector: Это селектор, который используется для поиска DOM-узла, из которого выбираются фильтры фасетов.

resultSelector: Это селектор, который используется для поиска DOM-узла, где отображаются результаты.

resultTemplate: Строка, которая используется Underscore шаблонизатором Для рендеринга каждого элемента из массива items . Следующие атрибуты добавляются к каждому элементу, который также можно использовать в шаблоне: batchItemNr , batchItemCount и totalItemCount .

state: Этот объект сохраняет текущие фильтры, сортирует: currentResult и прочие. Вы можете предоставить строку orderBy или объект filters для их предварительной настройки.

enablePagination: Boolean для включения пагиналора и кнопи "load more", по умолчанию true .

paginationCount: Если включен пагинатор, задаёт количество элементов на страницу, по умолчанию - 50.

facetSortOption: Используйте эту функцию, чтобы изменить порядок элементов фасетов. Принимает объект, в котором ключи соответствуют именам фасетов и значениям в массив значений фасетов, которые могут быть расположены в том порядке, в котором вы хотели бы их видеть. В этом примере будут отсортированы континенты в другом порядке, элементы, не включенные в массив, будут добавлены в алфавитном порядке:

FacetSortOption: {"continent": ["North America", "South America"]}

Есть еще несколько шаблонов, пожалуйста, посмотрите исходный код facetedsearch.js , чтобы увидеть все доступные параметры шаблона.

События

Вы можете привязываться к некоторым событиям, которые должны отправить уведомления, когда произошли некоторые действия. Для этого используем систему событий jquery:

facetuicreated: Вы можете привязать эту функцию к DOM элементу settings.facetSelector который должен быть уведомлен, когда пользовательский интерфейс был создан.

facetedsearchresultupdate: Вы можете привязать эту функцию к DOM элементу settings.resultSelector что бы получить уведомление о результатах обновления.

facetedsearchfacetclick: Это событие вызывается при щелчке фасета и его срабатывании на settings.facetSelector элементе. Который получает идентификатор фасета как аргумент.

facetedsearchorderby: Это событие вызывается при щелчке элемента сортировки по элементу settings.facetSelector. Он получает ID order в качестве аргумента.

$(settings.resultSelector).bind("facetedsearchresultupdate", function(){ // do something, maybe });

{ "query": { "and": [ { "terms": {"country": ["be", "fr"]} }, { "terms": {"category": ["books", "movies"]} } ] } }

Для счетчиков мы можем использовать встроенные агрегаты из Elasticsearch. Каждый из двух фасетов хранится как одно поле в индексе, поэтому мы можем использовать агрегирование терминов в каждом из этих полей. Агрегация вернет счетчик за значение этого поля.

{ "query": { "and": [ { "terms": {"country": ["be", "fr"]} }, { "terms": {"category": ["books", "movies"]} } ] }, "aggregations": { "countries": { "terms": {"field": "country"} }, "categories": { "terms": {"field": "category"} } } }

Если бы вы выполнили этот запрос, вы заметите, что счетчики отключены. В двух не отобранных странах, в Португалии и Бразилии, есть счетчик 0. Хотя есть фактические результаты, если мы хотим их выбрать (из-за ORвнутренней грани). Это происходит потому, что по умолчанию Elasticsearch выполняет свои агрегирования в результирующем наборе. Это означает, что если вы выберете Францию, фильтры другой страны будут иметь счет 0, потому что в результирующем наборе содержатся только элементы из Франции.

Чтобы исправить это, нам нужно дать команду Elasticsearch выполнить агрегацию во всем наборе данных, игнорируя запрос. Мы можем сделать это, определив наши скопления как глобальные.

{ "query": { "and": [ { "terms": {"country": ["be", "fr"]} }, { "terms": {"category": ["books", "movies"]} } ] }, "aggregations": { "all_products": { "global": {}, "aggregations": { "countries": { "terms": {"field": "country"} }, "categories": { "terms": {"field": "category"} } } } } }

Если бы мы просто сделали это, наши счетчики всегда были бы одинаковыми, потому что они всегда будут рассчитывать на весь набор данных, независимо от наших фильтров. Наши агрегаты должны стать немного более сложными, чтобы это работало, нам нужно добавить к ним фильтры. Каждое агрегирование должно рассчитывать на набор данных со всеми применяемыми фильтрами, за исключением собственных. Таким образом, агрегация за счет во Франции рассчитывает на набор данных с применением фильтра категории, но не фильтр стран:

{ "query": { "and": [ { "terms": {"country": ["be", "fr"]} }, { "terms": {"category": ["books", "movies"]} } ] }, "aggregations": { "all_products": { "global": {}, "aggregations": { "countries": { "filter": { "and": [ { "terms": {"category": ["books","movies"]} } ] }, "aggregations": { "filtered_countries": { "terms": {"field": "country"} } } }, "categories": { "filter": { "and": [ { "terms": {"country": ["be","fr"]} } ] }, "aggregations": { "filtered_categories": { "terms": {"field": "category"} } } } } } } }

{ "took": 153, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 3, "max_score": 0, "hits": ["..."] }, "aggregations": { "all_products": { "doc_count": 21, "filterted categories": { "doc_count": 13, "categories": { "doc_count_error_upper_bound": 0, "sum_other_doc_count": 0, "buckets": [ { "key": "movies", "doc_count": 6 }, { "key": "music", "doc_count": 4 }, { "key": "books", "doc_count": 3 } ] } }, "filtered_countries": { "doc_count": 15, "countries": { "doc_count_error_upper_bound": 0, "sum_other_doc_count": 0, "buckets": [ { "key": "fr", "doc_count": 6 }, { "key": "br", "doc_count": 4 }, { "key": "be", "doc_count": 3 }, { "key": "pt", "doc_count": 2 } ] } } } } }

Yii2 framework $terms = QueryHelper:: terms ("categories.name" , "my category" ) ; $nested = QueryHelper:: nested ("string_facet" , QueryHelper:: filter ([ QueryHelper:: term ("string_facet.facet_name" , [ "value" => $id , "boost" => 1 ] ) , QueryHelper:: term ("string_facet.facet_value" , [ "value" => $value , "boost" => 1 ] ) , ] ) ) ; $filter = QueryHelper:: should ($nested ) ; Встроенный фасетный поискВстроен в продукт

Встроенный в интернет-магазин фасетный поиск - внутренний поиск - работает быстро по многим параметрам и не нагружает при этом систему.

  • Встроен в продукт
  • Очень быстрый
  • Не нагружает сайт
  • Является основной частью API инфоблоков
  • Не требует переделки сайтов
  • Автоматически переиндексируется
Почему очень быстрый?

Клиенту моментально выводится заранее подготовленные результаты поиска - по любой комбинации параметров - фасете. Система заранее просчитывает фасеты для товара - всевозможные пересечения этих свойств в фильтре. Эти готовые поисковые наборы потом выдаются клиентам.

Почему не нагружает сайт?

В момент выдачи результата клиенту не происходит никаких вычислений, потому что результат уже готов. Фасета для нового товара создается сразу же при добавлении его в торговый каталог. Поиск автоматически переиндексируется в зависимости от новых товаров и новых свойств.

Преимущества для клиентов

Преимущества фасетного поиска Ваш клиент очень быстро находит товар, легко играя настройками фильтра. Клиент не ждет и моментально получает результат. Скорость поиска не зависит от количества элементов в каталоге.


«Умный» фильтр 2.0

Клиент быстро находит товар

Ваш клиент очень быстро находит товар, последовательно сужая поисковый запрос. И на каждом шаге он моментально получает результаты - список товаров по запросу. Ему не нужно ждать, пока его запрос обработается. Потому что система заранее просчитала все возможные варианты, и просто выдает заготовки. Постепенно интернет-магазин выдает в качестве результатов все меньше товаров. Эти товары все ближе подходят под запрос покупателя.

Интерактивность и многомерность

Выбор товара для покупателя напоминает игру. Клиент перетаскивает позунки параметров (цена, вес), переключает свойства (цвет, размер), задает дополнительные условия (бренд, материал, вкус и т.д.), - и система немедленно перестраивает результаты. При этом настраиваемых параметров может быть сколько угодно - их количество не сказывается на скорости формирования результата.

Удобство и дружелюбность

С фасетной навигацией даже неопытный пользователь легко подберет себе товар в магазине. Манипулировать инструментами поиска очень удобно. К тому же система подсказывает покупателю все параметры, по которым он может выбирать товар. Магазин как бы демонстрирует клиенту основные свойства товара.

Клиент не ждет обработки запроса!
Например, ваш клиент покупает фотоаппарат. Первоначально он указывает в умном фильтре всего 3 параметра: цена, бренд, размер. Его фасета включает 3 пересечения, результатов поиска много, но клиент их получает немедленно. Клиент задает вес - ему нужен легкий гаджет. Система тут же, без задержки выдает ему меньший список товаров. Клиент задает размер экрана, потом уточняет нужный функционал. Перед ним - искомые товары.


Скорость поиска

Скорость поиска имеет значение Скорость поиска влияет на число совершаемых покупок

Ничто так не выводит клиента из себя, как проблемы с поиском товаров на вашем сайте. Клиент уйдет в другие магазины, если будет искать слишком долго. Даже если ваш магазин содержит большой выбор товаров и множество инструментов для их фильтрации. Клиент может не дождаться результатов по запросу.


Видеооурок: Почему фасетный поиск ускоряет умный фильтр в разы
Использование «фасеты» на порядок ускоряет поиск внутри магазина. При этом скорость не зависит от количества элементов в каталоге.

Почему поиск работает слишко медленно?
Поиск товара на витрине магазина может выполняться значительно дольше обычного времени загрузки страниц. Особенно при наличии большого количества товаров в магазине и свойств у этих товаров. Поисковый запрос по многим параметрам создает очень много обращений к базе данных и значительно нагружает сайт. Если клиентов и запросов много, поиск ощутимо замедляется.

Скорость работы впечатляет! Результаты теста версии 15.0 продукта на трех категориях каталогов, содержащих 500 тысяч наименований показали, что по сравнению с предыдущими версиями:
  • Компонент умного фильтра – в 15 раз быстрее!
  • Компонент каталога – в 5 раз быстрее!
Интеллект поиска остается постоянным!
Быстро даже без «фасеты»! В продукте постоянно ведется работа над ускорением самих компонетов каталога. Сервис «Скорость сайта» показывает значительное повышение скорости от версии к версии!

Реконструкция

Выполняется постоянная реконструкция индексации и выдачи поиска. Перерабатывается и ускоряется алгоритм индексации контента. Повышается качество представления результатов поиска - в частности, снижается «зашумленность». В планах разработчиков - выводить в результатах поиска персонализированные данные для текущего клиента.

Разработчкам: прозрачность для API


Прежний вид

«Фасета» прозрачна для API Встроенная в продукт «фасета» прозрачна для API. Является основной частью API инфоблоков. Поэтому для ее использования не нужны дополнительные усилия для разработчиков. Также не требуется и переделка сайтов.
  • Ускорение метода CIBlockElement::GetList
  • Полная интеграция с умным фильтром
GetList теперь работает быстрее, потому что для своего функционирования автоматически подключает «фасету». Также появился отдельный API на D7.

Полная интеграция с умным фильтром

Теперь, выполняя настройки в административной части, для свойств товаров можно не только проставить активность - участвовать или нет в умном фильтре. Передавая свойство в Умный фильтр, вы можете сразу же выбрать вариант их отображения. В каком виде показывать свойство клиентам: кнопки, размеры, ползунки, выпадающие списки, списки с выбором цвета и т.д.



Показывать свойство в Умном фильтре

Поддается кастомизации!

Умный фильтр стал выглядеть красивее. Разработчики могут легко кастомизировать и настраивать дополнительно его внешний вид.