PINQ - Опрашиваемые наборы данных. Фасеточный поиск. В поисках верного пути: как фасетная навигация влияет на SEO (перевод)

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

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

- Раздел : аудиотехника (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

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

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

Но сначала 15 секунд политинформации (сам себя не похвалишь, никто не похвалит). В этом году Sphinx прошел во в номинациях SysAdmins и Enterprise (говорят, в номинации Developers не добрали совсем чуть-чуть). Голосование продлится еще неделю (до 20го числа). Кроме рабочего email адреса, ничего не нужно. Заранее спасибо всем, кто не даст нам пропасть!

И обратно к разработке. Что вообще такое мульти-запросы, и откуда берется обещанное втрое быстрее?

Мульти-запросы (multi-queries) - это механизм, который позволяет отослать несколько поисковых запросов одним пакетом.

Методы API, реализующие механизм мульти-запросов, называются AddQuery() и RunQueries() . (Кстати, «обычный» метод Query() внутри использует их же: один раз вызывает AddQuery(), и затем сразу RunQueries()). Метод AddQuery() сохраняет текущее состояние всех настроек запроса, выставленных предыдущими API вызовами, и запоминает запрос. Настройки уже запомненного запроса более меняться не будут, любый вызовы API их не тронут, соотв-но для последующих запросов можно использовать любые другие настройки (другой режим сортировки, другие фильтры, итп). Метод RunQueries() фактически отсылает все запомненные запросы одним пакетом и возвращает несколько результатов. На участвующие в пакете запросы никаких ограничений не накладывается. Количество запросов на всякий случай ограничено директивой max_batch_queries (добавлена в 0.9.10, ранее фиксированным числом 32), но это в общем-то только проверка против битых пакетов.

Зачем использовать мульти-запросы? Вообще говоря, все сводится к производительности. Во-1х, отсылая запросы к searchd одним пакетом, всегда экономим немножко ресурсов и времени на том, что отсылаем туда-сюда меньше сетевых пакетов. Во-2х, что значительно более важно, searchd получает возможность провести некоторые оптимизации над всем пакетом запросов. Со временем постепенно добавляются новые оптимизации, поэтому имеет смысл всегда, когда можно, отсылать запросы пакетами - тогда при обновлении Sphinx новые пакетные оптимизации включатся полностью автоматически. В случае, когда никаких пакетных оптимизаций применить нельзя, запросы просто будут обработаны по одному, без каких-либо видимых отличий для приложения.

Зачем (точнее когда) мульти-запросы НЕ использовать? Все запросы в пакете должны быть независимы, но иногда это не так, и запрос Б может зависеть от результатов запроса А. Например, можем хотеть показывать результаты поиска из дополнительного индекса только тогда, когда в главном индексе ничего не нашлось. Или просто выбирать разное смещение во 2й набор результатов в зависимости от количества совпадений в 1м наборе. В таких случаях придется использовать отдельные запросы (или отдельные пакеты).

Есть две важные пакетные оптимизации, про которые стоит знать: оптимизация общих запросов (доступна начиная с версии 0.9.8), и оптимизация общих поддеревьев (доступн начиная с находящейся в разработке версии 0.9.10).

Оптимизация общих запросов работает так. searchd выбирает из пакета все запросы, у которых отличаются только настройки сортировки и группровки, а полнотекстовая часть, фильтры итп совпадают - и проводит поиск только один раз. Например, если в пакете 3 запроса, текстовая часть у всех «ipod nano», но 1й запрос выбирает 10 самых дешевых результатов, 2й группирует результаты по ID магазина и сортирует магазины по рейтингу, а 3й запрос просто выбирает максимальную цену, поиск «ipod nano» отработает только один раз, но из его результатов будут построены 3 по-разному отсортированных и сгруппированных отклика.

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

Оптимизация общих поддеревьев еще более интересная штука. Она позволяет searchd использовать сходства между разными запросами внутри пакета. Внутри всех пришедших отдельных - разных! - полнотекстовых запросов выявляются общие части, и если такие есть, промежуточные результаты расчета кешируются и разделяются между запросами. Например, вот в таком пакете из 3 запросов

Barack obama president barack obama john mccain barack obama speech

Есть общая часть из 2х слов («barack obama»), которую можно для всех трех запросов вычислить ровно один раз и закешировать. Именно этим оптимизация общих поддеревьев и занимается. Максимальный размер кеша на каждую пачку жестко ограничивается директиваи subtree_docs_cache и subtree_hits_cache, так что если общая часть «i am» найдется в ста миллионах документов, память у сервера внезапно таки не кончится.

Вернемся обратно к оптимизации про общие запросы. Вот пример кода, который запускает один и тот же запрос, но с тремя разными режимами сортировки:
sorting modes:

Require ("sphinxapi.php"); $cl = new SphinxClient (); $cl->SetMatchMode (SPH_MATCH_EXTENDED2); $cl->SetSortMode (SPH_SORT_RELEVANCE); $cl->AddQuery ("the", "lj"); $cl->SetSortMode (SPH_SORT_EXTENDED, "published desc"); $cl->AddQuery ("the", "lj"); $cl->SetSortMode (SPH_SORT_EXTENDED, "published asc"); $cl->AddQuery ("the", "lj"); $res = $cl->RunQueries();

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

0.040 sec x3 the 0.040 sec x3 the 0.040 sec x3 the

Обратите внимание на «x3», это именно оно - означает, что запрос был оптимизирован и обработан в числе пакета из 3 запросов (включая этот). Для сравнения, вот так выглядит лог, в котором те же самые запросы были отправлены по одному:

0.059 sec the 0.091 sec the 0.092 sec the

Видно, что время поиск на каждый запрос в случае с мульти-запроса улучшилось от 1.5 до 2.3 раз, в зависимости от режима сортировки. На самом деле, это не предел. Для обоих оптимизаций известны случаи, когда скорость улучшалась в 3 и более раз - причем не на синтетических тестах, а вполне себе в продакшне. Оптимизация общих запросов довольно хорошо ложится на вертикальные поиски по товарам и онлайн магазины, кеш общих поддеревьев соовт-но на data mining запросов; но, разумеется, строго этими областями применимость не ограничивается. Например, можно делать поиск вообще без полнотекстовой части и считать несколько разных отчетов (с разной сортировкой, группировкой итп) по одинаковым данных за один запрос.

Каких еще оптимизаций можно ожидать в будущем? Зависит от вас. Пока что в долгосрочном плане записана понятная оптимизация про одинаковые запросы с разными наборами фильтров. Знаете другой частый паттерн, котороый можно ловко соптимизировать? Присылайте!

Мы кратко рассмотрели установку и базовый синтаксис 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 для получения агрегированной информации.

Заключение

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

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

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

Лучше всего продемонстрировать принцип фасетной навигации на конкретном примере.

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

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

Рассмотрим основные затруднительные вопросы.

1. Как много фасетов необходимо, чтобы ваш сайт был качественно проиндексирован?

В идеале, «глубина» фасета не должна превышать 100 наименований. Это позволит поисковым роботам проиндексировать все страницы ресурса. Большинство специалистов по продвижению сайтов склонны полагать, что поисковые роботы могут распознать более 100 ссылок на одной странице.

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

2. Фасеты и поисковые фильтры

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

3. Сортировка

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

4. Проблема дублированного контента

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

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

И еще раз об уникальности контента…

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

Итак, вот что следует запомнить:

  1. создавайте так много фасетов, сколько необходимо для размещения на одной странице не более 100 товаров;
  2. убедитесь, что для каждой ключевой фразы, по которой вы хотите ранжироваться в поисковых системах, существует своя целевая страница;
  3. неправильная сортировка может приводить к появлению дублированного контента, чтобы этого избежать используйте Ajax и Java Script для закрытия некоторых внутренних страниц от индексации;
  4. не важно, каким навигационным путем пользователь находит ту или иную страницу, индексироваться должна только одна страница;
  5. не забывайте: информационное наполнение должно быть интереснее и привлекательнее.

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

Поисковые алгоритмы

Поддерживайте оператор расширенного поиска «кавычки»

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

Кавычки - единственное исключение. Если заключить фразу в кавычки, то поиск будет вестись по полному совпадению с фразой. Такой оператор используется в поиске Google, и широко известен среди продвинутых пользователей интернета.

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

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

Пример. В предыдущих исследованиях пользователи сайта The Container Store жаловались на неточные результаты поиска на сайте. Один пользователь хотел приобрести комплект контейнеров для хранения из нержавейки с прозрачной крышкой. По запросу «сталь стекло контейнер» он получил в выдаче ёршики для унитаза и стеклянные банки. Пользователю пришлось переформулировать поисковый запрос несколько раз, но безуспешно.

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

Улучшенная выдача на сайте containerstore.com: первый же результат по запросу steel and glass canister соответствует потребности пользователя

При сортировке выдачи по оценке товара учитывайте ее взвешенное, а не среднее значение

Сортируя товары по средней оценке покупателей, пользователи не хотят видеть товары с единственной оценкой, даже если это 5 звезд. Люди не хотят наткнуться на заказной обзор, и средняя оценка товара, основанная на паре-тройке отзывов, вызывает у них подозрения. При сортировке по взвешенной оценке продукт со средней оценкой 4,9 из 5 и с 342 отзывами будет расположен выше, чем продукт со средней оценкой 5 из 5 и 3 отзывами. Таким образом пользователь сможет получить объективное представление о популярности и качестве товара.

Оформление и положение поисковой строки

Отображайте поисковую строку в одном блоке с навигационным меню в шапке сайта

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

На сайте Wildberries большая и хорошо заметная поисковая строка находится прямо в шапке сайта

Отображайте на экране поисковую строку и иконку лупы

Когда посетители сайтов интернет-магазинов хотят воспользоваться поиском, они ищут взглядом широкое пустое поле или иконку лупы. При этом явно подписывать поисковую строку и называть ее «Поиск» больше не обязательно, хотя и не помешает.

Многие сайты в версиях для смартфонов успешно используют иконку лупы и не показывают саму строку, что позволяет им экономить место на экране. Но если продажи на вашем сайте зависят от поиска, лучше отображать поисковую строку сразу, даже на маленьких экранах. Тем более это актуально для ПК-версий сайтов, где места на экране более чем достаточно. Используйте пустое поле с кнопкой «Найти» или иконкой лупы. Поле должно быть заметно на каждой странице.

Сужение результатов поиска

Не используйте расширенный поиск и поиск по категориям, если вы не Amazon

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

Такие продвинутые способы поиска сейчас остались только на тех сайтах, где они действительно полезны. Это либо сайты с особыми сценариями поиска, вроде eBay, либо интернет-магазины с огромным количеством товаров, такие, как Amazon и Wal-Mart .

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

Используйте фасетный поиск

Фасетный поиск позволяет пользователям сократить результаты поиска с помощью фильтров, основанных на атрибутах товаров, которые пользователи рассматривают. Если раньше фасетный поиск был приятным дополнением в интернет-магазине, то сейчас пользователи так привыкли к нему, что ищут его на сайте и выражают недовольство, если его нет. Сейчас e-commerce сайты без фасетного поиска - скорее исключение, чем правило.

Фасетный поиск на сайте интернет-магазина «Утконос»: фильтры слева позволяют сузить выдачу

Автодополнение в поисковой строке

Поддерживайте функцию автодополнения

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

Функция автодополнения присутствовала на большинстве изученных NNGroup сайтов. При этом исследование показало, что пользователи выбирали варианты из списка предложенных не так уж и часто - всего в 23% случаев. Как правило, они просто продолжали вводить свой запрос.

Тем не менее, автодополнение полезно. Даже если пользователи не выбирают вариант из списка, они могут увидеть и понять, какие товары доступны на сайте, и что ищут другие покупатели./p>

Поддерживайте расширенное автодополнение

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

Поиск с расширенным автодополнением в интернет-магазине «Лабиринт»

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

Основные проблемы поиска

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

  • незаметная функция поиска: например, скрытая за маленькой иконкой лупы на большом экране или в меню-гамбургере мобильной версии сайта;
  • недостаточно «умная» поисковая строка, неспособная обрабатывать опечатки, ошибки или синонимы к ключевым словам запроса;
  • нестандартное отображение результатов (переключение между страницами, сортировка, фильтрация);
  • непродуманные фильтры (нерелевантные атрибуты, плохая функциональность, пустые результаты).

Как компания USABILITYLAB может помочь улучшить поиск на сайте вашего интернет-магазина

На этом мы заканчиваем анализировать статью NNGroup. Надеемся, она была полезна для вас.

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

Чтобы больше узнать о наших услугах, оставьте заявку на нашем сайте или напишите Дмитрию Силаеву: