В поисках верного пути: как фасетная навигация влияет на SEO (перевод). Решения для фасетной навигации

Мы кратко рассмотрели установку и базовый синтаксис PINQ, портированную на PHP версию LINQ. В этой статье мы рассмотрим, как использовать PINQ для имитации возможности фасеточного (аспектного) поиска в MySQL.

В этой статье мы не будем рассматривать все аспекты фасеточного поиска. Интересующиеся люди могут поискать подходящую информацию в интернете.

Типичный фасеточный поиск работает следующим образом:

  • Пользователь вводит ключевое слово, или несколько ключевых слов для поиска. Например, “маршрутизатор” для поиска продуктов, у которых в слово “маршрутизатор” встречается в описании, ключевых словах, названии категории, тегах и проч.
  • Сайт возвращает список продуктов, подходящих под эти критерии.
  • Сайт предоставляет несколько ссылок для подстройки условий поиска. Например, может позволить указать конкретных производителей маршрутизаторов, либо задать диапазон цен, или другие особенности.
  • Пользователь может продолжать указывать дополнительные критерии поиска для того, чтобы получить интересующий его набор данных.

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

К сожалению, фасеточный поиск не встроен в MySQL. Так что же нам делать, если мы всё-таки используем MySQL, но хотим дать пользователю такую возможность?

С помощью PINQ, в котором реализован аналогичный, мощный и простой подход, мы можем добиться такого поведения, как если бы мы использовали другие движки баз данных.

Расширяем демонстрационный пример из первой части

Замечание : весь код из этой части, и из первой части, можно найти в репозитории .

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

Начнём с index.php , добавив в него следующие строки:

$app->get("demo2", function () use ($app) { global $demo; $test2 = new pinqDemo\Demo($app); return $test2->test2($app, $demo->test1($app)); }); $app->get("demo2/facet/{key}/{value}", function ($key, $value) use ($app) { global $demo; $test3 = new pinqDemo\Demo($app); return $test3->test3($app, $demo->test1($app), $key, $value); });

Первый маршрут переносит нас на страницу для просмотра всех записей, подходящих под поиск по ключевому слову. Чтоб не усложнять пример, мы выбираем все книги из таблицы book_book . На ней также будут отображён результирующий набор данных и набор ссылок для конкретизации критериев поиска.

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

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

Как видно в вышеприведённом коде, реальные функции располагаются в другом файле, под названием pinqDemo.php . Давайте взглянем на соответствующий код, который предоставляет возможность фасеточного поиска.

Класс аспекта

Первым делом создадим класс, представляющий аспект. В целом, аспект должен содержать несколько свойств:

  • Данные, которыми он оперирует ($data )
  • Ключ, по которому производится группировка ($key )
  • Тип ключа ($type). Может быть одним из следующих:
    • указывать полную строку, для точного совпадения
    • указывать часть строки (обычно - начальную), для поиска по шаблону
    • указывать диапазон значений, для группировки по диапазону
  • если тип ключа - диапазон значений, необходимо определить шаг значения для определения нижней и верхней границы диапазона; или же если тип - часть строки, необходимо указать, сколько первых букв будет использоваться для группировки ($range)

Группировка - наиболее критичная часть аспекта. Вся агрегированная информация, которую, возможно, сможет вернуть аспект, зависит от критериев группировки. Обычно наиболее используемыми критериями поиска являются “Полная строка”, “Часть строки”, или “Диапазон значений”.

Namespace classFacet { use Pinq\ITraversable, Pinq\Traversable; class Facet { public $data; // Оригинальный набор данных public $key; // поле, по которому производится группировка public $type; // F: вся строка; S: начало строки; R: диапазон; public $range; // играет роль, только если $type != F ... public function getFacet() { $filter = ""; if ($this->type == "F") // вся строка { ... } elseif ($this->type == "S") // начало строки { ... } elseif ($this->type == "R") // диапазон значений { $filter = $this->data ->groupBy(function($row) { return floor($row[$this->key] / $this->range) * $this->range; }) ->select(function (ITraversable $data) { return ["key" => $data->last()[$this->key], "count" => $data->count()]; }); } return $filter; } } }

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

Задаём аспекты и отображаем исходные данные

Public function test2($app, $data) { $facet = $this->getFacet($data); return $app["twig"]->render("demo2.html.twig", array("facet" => $facet, "data" => $data)); } private function getFacet($originalData) { $facet = array(); $data = \Pinq\Traversable::from($originalData); // 3 примера создания различных объектов аспектов, и возврат аспектов $filter1 = new \classFacet\Facet($data, "author", "F"); $filter2 = new \classFacet\Facet($data, "title", "S", 6); $filter3 = new \classFacet\Facet($data, "price", "R", 10); $facet[$filter1->key] = $filter1->getFacet(); $facet[$filter2->key] = $filter2->getFacet(); $facet[$filter3->key] = $filter3->getFacet(); return $facet; }

В методе getFacet() мы делаем следующее:

  • Конвертируем оригинальные данные в объект Pinq\Traversable для последующей обработки
  • Создаём три аспекта. Аспект ‘author’ будет группировать по полю author , и реализует группировку по всей строке; аспект ‘title’ - по полю title с группировкой по части строки (по первым 6 символам); аспект ‘price’ - по полю price с группировкой по диапазону (с шагом 10)
  • Наконец, извлекаем аспекты и возвращаем их функции test2 , чтобы их можно было вывести в шаблон для отображения

Вывод аспектов и отфильтрованных данных

В большинстве случаев фильтры будут отображены в виде строки, и будут вести к просмотру отфильтрованного результата.

Мы уже создали маршрут ("demo2/facet/{key}/{value}") для вывода результатов фасеточного поиска и ссылок фильтров.

Маршрут принимает два параметра, в зависимости от ключа, по которому производится фильтрация, и от значения для этого ключа. Функция test3 , которая привязана к этому маршруту, представлена ниже:

Public function test3($app, $originalData, $key, $value) { $data = \Pinq\Traversable::from($originalData); $facet = $this->getFacet($data); $filter = null; if ($key == "author") { $filter = $data ->where(function($row) use ($value) { return $row["author"] == $value; }) ->orderByAscending(function($row) use ($key) { return $row["price"]; }) ; } elseif ($key == "price") { ... } else //$key==title { ... } return $app["twig"]->render("demo2.html.twig", array("facet" => $facet, "data" => $filter)); }

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

Наконец, мы отображаем исходные данные (вместе с фильтрами) в шаблоне. Этот маршрут использует тот же шаблон, который мы использовали в " demo2 ".

Search Bar

    {% for k, v in facet %}
  • {{k|capitalize}}
    • {% for vv in v %}
    • {{vv.count}}{{vv.key}}
    • {%endfor%}
    {%endfor%}

Нужно помнить, что аспекты, генерируемые нашим приложением, являются вложенными массивами. На первом уровне это массив всех аспектов, и, в нашем случае их три (соответственно, для author , title , price).

У каждого аспекта есть массив “ключ-значение”, так что мы можем итерировать его обычными методами.

Заметьте, как мы строим URL для наших ссылок. Мы используем и ключ внешнего цикла (k), и ключи внутренних циклов (vv.key) в качестве параметров для маршрута ("demo2/facet/{key}/{value}"). Размер массивов (vv.count) используется для отображения в шаблоне.

На первом изображении представлен изначальный набор данных, а на второй - отфильтрованный по диапазону цен от 0$ до 10$, и отсортированный по автору.

Здорово, у нас получилось имитировать фасеточный поиск в нашем приложении!

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

Возможные улучшения

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

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

Ограничения

Фасеточный поиск, реализованный в этой статье, имеет серьёзные ограничения (что, возможно, относится и к другим реализациям фасеточного поиска):

Мы каждый раз выбираем данные из MySQL

Это приложение использует фреймворк Silex. Как и в любом фреймворке с единой точкой входа, вроде Silex, Symfony, Laravel, его файл index.php (или app.php) вызывается каждый раз, когда происходит анализ маршрута, и выполняются функции контроллера.

Если посмотреть в код в нашем index.php , можно обратить внимание, что следующая строчка кода:

$demo = new pinqDemo\Demo($app);

вызывается каждый раз, когда отображается страница приложения, что значит, что каждый раз выполняются следующие строки кода:

Class Demo { private $books = ""; public function __construct($app) { $sql = "select * from book_book order by id"; $this->books = $app["db"]->fetchAll($sql); }

Будет ли лучше, если мы не будем использовать фреймворк? Что ж, несмотря на факт того, что разрабатывать приложения без фреймворков, является не очень хорошей идеей, могу сказать, что мы встретимся с теми же проблемами: данные (и состояние) не сохраняются между разными HTTP запросами. Это фундаментальная характеристика HTTP. Этого можно избежать, используя механизмы кеширования.

Мы сэкономили несколько SQL запросов, используя аспекты. Вместо того, чтобы передать один select запрос на выборку данных, и три запроса group by с соответствующими условиями where , мы выполнили только один запрос where , и использовали PINQ для получения агрегированной информации.

Заключение

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

Мы выпустили новую книгу «Контент-маркетинг в социальных сетях: Как засесть в голову подписчиков и влюбить их в свой бренд».

Подписаться

Фасетная навигация – это проблема всех e-commerce сайтов. Чрезмерное количество страниц, которые используются для разных вариантов одного и того же элемента, создает угрозу эффективности поиска. Это может негативно повлиять на SEO и пользовательский опыт. Что такое фасетная навигация, и как ее улучшить, рассказали специалисты из блога SEO Hacker.

Фасетная навигация: определение

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

Фасеты и фильтры отличаются друг от друга. Вот в чем заключается разница:

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

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

Потенциальные проблемы

У каждой возможной комбинации фасетов есть собственный уникальный URL-адрес. Он может стать причиной некоторых проблем с точки зрения SEO. Вот основные из них:

  • Дублированный контент.
  • Трата бюджета на сканирование.
  • Устранение разницы в ссылках.

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

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

Решения для фасетной навигации

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

AJAX

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

AJAX может быть эффективен только до запуска сайта e-commerce. Для решения проблем уже существующих ресурсов он не используется. Также этот метод требует определенных трат с вашей стороны.

Тег noindex

Тег noindex используется для того, чтобы боты исключили определенную страницу из индекса. Таким образом она не будет отображаться в результатах поиска Google. Это позволяет уменьшить количество дублированного контента, отображаемого в индексе и результатах поиска.

Это не решит проблемы с бюджетом на обход, потому что боты все равно будут посещать вашу страницу. Это также не помогает распределить ценность ссылок.

Атрибут rel=canonical

С помощью этого атрибута вы сообщаете Google, что у вас есть одна основная предпочтительная страница для индексирования и ранжирования, а все остальные версии контента с этой страницы – всего лишь дубликаты, которые не нужно индексировать.

София Ибрагимова

Контент-маркетолог

Если на одну и ту же страницу вашего сайта можно попасть по нескольким URL-адресам, поисковые роботы будут расценивать каждый адрес как отдельную страницу. Боты решат, что контент на вашем сайте неуникален, а это отрицательно скажется на ранжировании и снизит ваши позиции в выдаче. Чтобы этого избежать, укажите основную каноническую страницу, вставив в блок HEAD следующую последовательность символов:

Вы можете использовать канонические страницы, чтобы решить проблему дублирования контента, а привязка акций будет объединена с вашей основной страницей. Но есть вероятность, что боты все равно будут сканировать дублированные страницы, а это пустая трата бюджета на обход.

Robots.txt

Закрытие части страниц от индексации позволяет добиться хороших результатов. Это простой, быстрый и надежный способ. Удобнее всего установить настраиваемый параметр для указания всех возможных комбинаций фасетов и фильтров, которые вы хотите заблокировать. Включите его в конец каждого URL-адреса, который хотите скрыть (http://полный адрес страницы/robots.txt) или используйте метатег Robots в области HEAD кода страницы.

При изменении в URL-адресе необходимо помнить, что роботам требуется 3-4 недели, чтобы заметить эти изменения и среагировать на них.

Здесь тоже существуют определенные проблемы. Ценность ссылок будет ограничена, а также заблокированный URL может быть проиндексирован из-за наличия внешних ссылок.

Консоль Google Search

Это отличный способ временно исправить свои проблемы, пока вы работаете над созданием более совершенной и удобной системы навигации. Вы можете использовать консоль Google Search, чтобы сообщить поисковику, как сканировать ваш сайт.

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

Помните, что этот способ скрывает дублированный контент только от поисковых роботов Google. В Bing и Yahoo станицы по-прежнему будут отображаться.

Как улучшить фасетную навигацию

Рассмотрим вкратце все методы, которые позволяют создать правильную фасетную навигацию:

  • Использование AJAX
  • Удаление или скрытие ссылок на категории или страницы фильтров, на которых отсутствует контент.
  • Разрешение индексирования определенных комбинаций фасетов, которые имеют большой объем поиска трафика
  • Установка иерархии сайтов через хлебные крошки в категориях и подкатегориях.
  • Создание канонических (основных) страниц для дублированного контента.
  • Консолидация индексирующих свойств со страниц компонентов на весь ряд с помощью разметки страницы с rel = "next" и rel = "prev" .

Заключение

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

Содержание статей:
Предыдущая статья:

Фасеты - это определенные ограничения на тип значений XDTO. Один фасет определяет тип ограничения и значение ограничения. Например [Максимум включающий - 5]. Тип значения XDTO может хранить в себе несколько фасетов, но их типы должны быть уникальны, то есть нельзя указать два фасета [Максимум включающий - 5] и [Максимум включающий - 3].

В данной статье хочу показать как можно при помощи фасетов сделать проверку входных и как сделать параметр ws-операции составного типа.

Поставим простую задачу - сделать выгрузку номенклатуры через веб-сервис. Будем выгружать код, наименование, цену и остаток в магазине. Но справочник может быть очень большим, потому при вызове ws-операции должна быть возможность установить отбор. Будем отбирать по коду номенклатуры.

Создадим новую базу и добавим новый пакет XDTO, назовем его ПакетXDTO, укажем пространство имен.

Далее добавим в пакет Тип значения как показано на рисунке.


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


Теперь таким же образом создадим ТипЗначения "Цена". Для него установим минимум 0, максимум 1 000 000.


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


Ну, теперь приступим к созданию веб-сервиса. Назовем его "Остатки" и добавим 3 параметра:
  • Код - тип Код, который мы ранее создали. По данному параметру будем устанавливать отбор на код номенклатуры;
  • ЦенаОт - тип Цена. Это нижняя граница цены товара;
  • ЦенаДо - тип Цена. Это верхняя граница цены товара.

Для того что бы веб сервис вывел массив товаров, у каждого из которых есть код, наименование, цена и остаток создадим ОбъектXDTO "Номенклатура", в котором укажем поля:

  • Код - тип Код;
  • Наименование - тип string;
  • Цена - тип Цена;
  • Остаток - тип int

И создадим ОбъектXDTO "Товары", который будет иметь одно свойство "Номенклатура", но с возможностью вывода списком. В качестве типа поля "Номенклатура" объекта "Товары" укажите объект "Номенклатура". Подробнее о том как передать массив через веб-сервис можно прочитать .

Перейдем к свойствам операции "Остатки". Укажем тип возвращаемого значения - "Товары" и откроем ее модуль. Напишем такой код:

Функция Остатки (Код , ЦенаОт , ЦенаДо )

Запрос = Новый Запрос;
Запрос . Текст =
"ВЫБРАТЬ
|Номенклатура.Код,
|Номенклатура.Наименование,
|Номенклатура.Цена,
|Номенклатура.Остаток
|ИЗ
|Справочник.Номенклатура КАК Номенклатура
|ГДЕ
|1 = 1
|И 2 = 2" ;

Если ЗначениеЗаполнено (Код )
И Код <> " 000000000 " Тогда
Запрос . Текст = СтрЗаменить (Запрос . Текст , " 1 = 1 " , " Номенклатура.Код = &Код " );
Запрос . УстановитьПараметр (" Код " , Код );
КонецЕсли;

Если НЕ ЦенаОт = ЦенаДо Тогда
Запрос . Текст = СтрЗаменить (Запрос . Текст , "2 = 2" , "Номенклатура.Цена МЕЖДУ &ЦенаОт И &ЦенаДо" );
Запрос . УстановитьПараметр ("ЦенаДо" , ЦенаДо );
Запрос . УстановитьПараметр ("ЦенаОт" , ЦенаОт );
КонецЕсли;

РезультатЗапроса = Запрос . Выполнить ();

ВыборкаДетальныеЗаписи = РезультатЗапроса . Выбрать ();
ТипXDTOТовары = ФабрикаXDTO . Тип (, "Товары" );

Товары = ФабрикаXDTO . Создать (ТипXDTOТовары );
ТипXDTOНоменклатура = ФабрикаXDTO . Тип ("http://codenotes-1c.blogspot.ru/" , "Номенклатура" );
Пока ВыборкаДетальныеЗаписи . Следующий () Цикл
Номенклатура = ФабрикаXDTO . Создать (ТипXDTOНоменклатура );
Номенклатура . Код = ВыборкаДетальныеЗаписи . Код ;
Номенклатура . Наименование = ВыборкаДетальныеЗаписи . Наименование ;
Номенклатура . Цена = ВыборкаДетальныеЗаписи . Цена ;
Номенклатура . Остаток = ВыборкаДетальныеЗаписи . Остаток ;
Товары . Номенклатура . Добавить (Номенклатура );
КонецЦикла ;

Возврат Товары ;

КонецФункции

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

  • без параметров. Если быть точным то укажем код "000000000", цену от =0, цену до = 0. Потому что, пустые параметры недопустимы.

Ну и у параметра "Код" ws-операции "Остатки" укажем этот тип. После чего мы сможем указывать код номенклатуры как в виде числа, так и в виде строки. Без переделки кода можем указать только 0, что соответствует пустому значению параметра, и отбор не будет установлен.

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

Далее, в качестве справки приведу значение каждого поля свойства. Данное описание взято по ссылке: К чему относится понятие «Фасет» в рамках модели XDTO? Что такое фасет? Авторам большое спасибо!

  • Базовый тип - тип, который используется как основа. По умолчанию anyType. От этого значения зависит допустимый набор фасетов.
  • Длина — фасет длины. Содержит количество единиц длины, причем единица длины имеет различный смысл для различных типов. Для типов «string» и «anyURI» длина содержит количество символов. Для типов «hexBinary» и «base64Binary» длина содержит количество байт двоичных данных. Для типов, определяемых списком, длина содержит количество элементов списка;
  • МаксВключающее — фасет максимума, включающего границу. Ограничивает пространство значений данного типа максимальным значением. Любое значение данного типа меньше либо равно указанному значению;
  • МаксДлина — фасет максимальной длины. Содержит максимальное количество единиц длины, причем единица длины имеет различный смысл для различных типов. Для типа «string» максимальная длина содержит максимальное количество символов. Для типов «hexBinary» и «base64Binary» максимальная длина содержит максимальное количество байт двоичных данных. Для типов, определяемых списком, максимальная длина содержит максимальное количество элементов списка;
  • МаксИсключающее — фасет максимума, не включающего границу. Ограничивает пространство значений данного типа максимальным значением. Любое значение данного типа меньше указанного значения;
  • МинВключающее — фасет минимума, включающего границу. Ограничивает пространство значений данного типа минимальным значением. Любое значение данного типа больше либо равно указанному значению;
  • МинДлина — фасет минимальной длины. Содержит минимальное количество единиц длины, причем единица длины имеет различный смысл для различных типов. Для типа «string» минимальная длина содержит минимальное количество символов. Для типов «hexBinary» и «base64Binary» минимальная длина содержит минимальное количество байт двоичных данных. Для типов, определяемых списком, минимальная длина содержит минимальное количество элементов списка;
  • МинИсключающее — фасет минимума, не включающего границу. Ограничивает пространство значений данного типа минимальным значением. Любое значение данного типа больше указанного значения;
  • Перечисление — фасет перечисления. Определяет набор допустимых значений данного типа;
  • ПробельныеСимволы — фасет пробельных символов. Может принимать одно из трех значений:
    • Сохранять — строка может содержать любые пробельные символы;
    • Заменять — строка не должна содержать #x9 (табуляция), #xA (перевод строки) и #xD (возврат каретки). Если они существуют, то они должны быть заменены символом #x20 (пробел);
    • Сворачивать — дополнительно к требованиям, указанным для значения replace, строка не должна содержать парных символов #x20 (пробел), а также лидирующих и завершающих символов #x20 (пробел);
  • ЦифрВсего — фасет общего количества цифр. Содержит общее количество разрядов числа (целая часть плюс дробная часть);
  • ЦифрДробнойЧасти — фасет количества цифр дробной части. Содержит количество разрядов дробной части числа.

Татьяна Старкова

Сложность урока:

3 уровень - средняя сложность. Необходимо внимание и немного подумать.

Недоступно в редакциях:

Ограничений нет

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

Примечание: фасетный поиск доступен с версии 15.0.1 модуля Информационные блоки .

Немного "скучной теории" о фасетном поиске

Система заранее формирует фасеты (всевозможные комбинации пересечения свойств товаров) и при выполнении поискового запроса сразу выдается результат - эти готовые фасеты. Механизм фасетного поиска встроен в информационные блоки и интегрирован с компонентом Компонент - это программный код, оформленный в визуальную оболочку, выполняющий определённую функцию какого-либо модуля по выводу данных в Публичной части. Мы можем вставлять этот блок кода на страницы сайта без непосредственного написания кода. Умный фильтр Компонент подготавливает фильтр для выборки из инфоблока и выводит форму фильтра для фильтрации элементов. Компонент должен подключаться перед компонентом вывода элементов каталога, иначе список элементов фильтроваться не будет. Компонент стандартный, входит в дистрибутив модуля и содержит три шаблона: .default , visual_horizontal и visual_vertical . (Последние два шаблона не поддерживаются, остались для сохранения совместимости.)

В визуальном редакторе компонент расположен по пути Контент > Каталог > Умный фильтр .

Компонент относится к модулю Информационные блоки.

Настройка фасетного поиска заключается в создании фасетных индексов и выполняется всего за несколько простых действий:


Созданные фасетные индексы хранятся в базе данных, а в таблице для каталогов товаров в колонке Состояние отображается Работает :

Примечание: для каталога предложений фасетные индексы создаются при создании индексов для основного каталога.

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

  1. создать фасетные индексы для каталога с товарами;
  2. следить за оповещением о необходимости пересоздания индексов.

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

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

- Раздел : аудиотехника (54), компьютерная техника (85)
- Брэнд : Apple (25), Samsung (68), iRiver (78)
- Наличие на складе : есть (456), нет (12)
- Цена : 100-1000$ (45), 1000-10000$ (12)

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


С одной стороны это альтернатива раскрытым фильтрам в Views, с другой альтернатива стандартному расширенному поиску.

Установка

Раздел Facets

В этом разделе можно указать, какие фасеты использовать при поиске. Например разрешить отбирать материалы по таксономии, дате добавления или автору. Число фасетов зависит от включённых модулей.

Раздел Results page

Display style - стиль вывода результатов поиска: Extracts значит выводить как при обычном поиске (подсвеченный текст, автор, дата); Teasers значит выводить тизеры материалов с помощью соответствующего node.tpl.php.

Use the Extracts display style selectively - Если опция отмечена, то стиль Extracts будет применяться всегда, если введено ключевое слово. Если не отмечать эту опцию то можно использовать модуль в качестве замены навигации по терминам таксономии.

Раздел Current search

Позволяет включить блок Текущий поиск , в котором отображаются условия поиска: