Любому сайту нужен поиск. Например, на Хабре сотни тысяч статей на самые разные темы. Чтобы отыскать ту самую через хабы и блоги, может потребоваться о-о-очень много времени. Без поиска пользователи могут не найти то, что им нужно, решить, что здесь этого нет и уйти в другой сервис.
В этой статье расскажу, через какие этапы обычно проходит внедрение поиска и как подход к нему меняется с ростом компании, какие задачи вам предстоит решить, а ещё — какие метрики помогут понять, что вы на верном пути.
Меня зовут Богдан Гаркушин. Я занимаюсь поиском примерно 20 лет: начинал как разработчик, потом стал менеджером продукта в Яндексе, после этого отвечал за поиск в Рамблере и теперь руковожу поисковым направлением ВКонтакте.
Расскажу о поисковых движках, ранжировании, архитектуре — а ещё о том, как оценить качество поиска. Посмотрим, какие решения будут наиболее адекватны на каждой жизненной стадии проекта: от стартапа до сервиса масштаба ВКонтакте.
Что будет в статье:
Этап № 0. Определяем метрики для оценки качества поиска
Этап № 1. Готовимся к запуску MVP
Этап № 2. Запускаем MVP и определяем функциональные требования
Этап № 3. Улучшаем качество поиска
Этап № 4. Строим архитектуру системы поиска для большого проекта
Этап № 0. Определяем метрики качества поиска
Прежде чем внедрять что-либо, нужно понять, на какие метрики ориентироваться. Поиск — не исключение.
Я выделяю три группы метрик:
конверсионные;
поисковые;
аудиторные.
Конверсионные метрики показывают соотношение людей, которые совершили целевое действие, к общему числу пользователей поиска. Целевые действия бывают разными и зависят от вашего проекта: например, для поиска по людям ВКонтакте это могут быть дружбы, для поиска по видео — просмотры, для поиска по музыке — прослушивания.
Поисковые метрики отражают релевантность результатов поиска запросам пользователя. Здесь оценивается, насколько высоко нужный результат показывается в поисковой выдаче — и отражается ли он там в целом. К метрике из этой группы относятся поиски с результатами или кликами.
Аудиторные метрики связаны с количеством людей, которые пользуются поиском. Они имеют накопительный эффект и меняются спустя время: пользователи могут постепенно приходить, если делать всё правильно, или уходить, когда им что-то не нравится. Показатели из этой группы показывают долгосрочный эффект, поэтому не стоит ждать от них быстрых изменений. Примеры аудиторных метрик — DAU (daily active users), MAU (monthly active users), поисковые сессии.
Этап № 1. Готовимся к запуску MVP
На первом этапе разработки нового проекта или продукта чаще всего есть только первые наброски архитектуры и макеты интерфейса в Figma. На этом этапе ещё почти нет аудитории, нагрузки, данных. Какие результаты поиска будут ожидать пользователи и, например, сколько результатов предстоит выводить, можно представить только ориентировочно.
Архитектура на этом этапе выглядит примерно так: есть приложение и есть API поиска, за которым просто стоит база данных.
Этап № 2. Запускаем MVP и определяем функциональные требования
На втором этапе, когда проект запущен и начинает набирать аудиторию, проявляются потребности пользователей и паттерны их поведения. Начинают приходить обращения через службу поддержки, становятся заметны изменения в метриках — это помогает формировать функциональные требования к поиску.
Конечно, не всегда все пожелания пользователей нужно реализовывать: иногда никому, кроме автора обращения в поддержку, это не нужно, а бывает, так и вовсе можно испортить пользовательский опыт.
Чаще всего изменения влияют в первую очередь на поисковые метрики — становится меньше ситуаций, когда в ответ на запрос пользователя поиск выдаёт ноль результатов. Нужно выяснить, точно ли это хорошо для человека — с помощью другой метрики. Например, если пользователь находит больше Дим в поиске, заводит ли он больше дружб?
Что касается архитектуры, то здесь появляется новый элемент — поисковый движок. Возникает проблема: базу данных сервиса нужно постоянно синхронизировать с поиском. Этот процесс называется индексацией.
На этом этапе, когда уже есть функциональные требования, можно рассмотреть готовые решения для поиска. Вот что я могу здесь посоветовать.
Sphinx — поиск интегрирован с СУБД и имеет API для Python, PHP, Java.
Векторный поиск Vespa — здесь ядро на C++, горизонтальное масштабирование, чтобы добавлять данные и не индексировать их снова, возможность использования машинного обучения и ориентация на Kubernetes.
Готовые движки ElasticSearch и Solr к библиотеке Lucena — помогают быстро стартовать, но испытывают проблемы при больших объёмах данных. Работают на Java.
Библиотека Lucene — основа для создания собственных решений поиска. Полезна, если вы разрабатываете крупное высоконагруженное решение: в библиотеке есть полнотекстовый и нечёткий поиск, она оптимизирована под современные процессоры, гибко расширяется и кастомизируется. Это же свойство будет минусом, так как многое придётся писать самостоятельно — бывает, что для этого нет ни потребностей, ни ресурсов. Lucene развивается уже 20 лет и поддерживает все нужные функциональные возможности поиска.
Этап № 3. Улучшаем качество поиска
Спустя некоторое время, когда проект набирает аудиторию и объём данных, результатов поиска становится много — под «много» имею в виду, что вся выдача не помещается на один экран, и её нужно как-то упорядочивать. Здесь приходит пора задуматься о качестве и искать способы его улучшить.
Когда я пришёл ВКонтакте, у меня была идея — сделать расстояние одним из критериев ранжирования поиска по людям в соцсети. Чтобы проверить гипотезу, наша команда обратилась к команде ленты и социального графа. Выяснилось, что на дружбы напрямую влияло расстояние: большинство всех добавлений в друзья происходило, если между людьми меньше 100 километров. Так мы поняли, что это важный критерий для пользователей, и решили внедрить его в поиск.
Гипотеза подтвердилась практическими результатами: ранжирование пользователей по расстоянию привело к тому, что количество дружб из результатов поиска выросло на 20%.
Чтобы улучшить качество поиска, нужно добавить в архитектуру ещё один элемент — формулу ранжирования. Конечно, её можно попробовать просто придумать на основе своего личного опыта.
Даже если добавить в поиск формулу ранжирования, этого может быть недостаточно — остаётся всё ещё много результатов. Поэтому появляется необходимость вводить новые критерии поиска.
Когда критериев становится пять и более, придумать формулу ранжирования, которая будет учитывать все закладываемые параметры, становится тяжело. На помощь приходит машинное обучение. Оно работает с онлайном и офлайном: в офлайне на исторических данных строится модель, в онлайне — собираем то, что знаем здесь и сейчас, и ранжируем согласно модели. Остаётся только правильно передавать данные в модуль, следить за метриками (снова!) и менять действия поиска в соответствии с результатами.
Когда мы добавили новые критерии ранжирования в поиск по людям ВКонтакте — фонемы, синонимы, транслитерацию и ML-ранжирование — число дружб из поиска выросло ещё на 25%. Это добавилось к тем 20%, которые мы получили благодаря расстоянию: в итоге увеличили количество дружб из результатов поиска почти в 1,5 раза.
Чтобы ещё лучше ранжировать результаты поиска и понимать пользователей, можно использовать более сложный ML. Технологии для работы с текстом, такие как FastText и BERT, позволяют строить векторное представление, находить синонимы и расширять поиск.
Сложный ML может быть полезен, например, для поиска в видео. Если человек ищет волшебника в очках, то он, скорее всего, имеет в виду фильм про Гарри Поттера. Улучшить такой поиск помогают дополнительные сигналы — их можно собрать из поста, в котором публикуется видео, и комментариев к нему.
Этап № 4. Строим архитектуру системы поиска
По мере развития продукта, а также роста аудитории и объёма данных, по которым осуществляется поиск, увеличивается нагрузка на систему. Приходит пора подумать о том, как контролировать нагрузку, чтобы поиск не ломался. Самый простой способ — использовать репликацию, то есть добавить один или несколько абсолютно таких же поисковых серверов с идентичными данными. В случае поиска также стоит применить балансировщик нагрузки для распределения запросов.
Репликация помогает защититься от временной потери данных и простоев в случае отказа одного из серверов.
Здесь может возникнуть и ещё одна проблема: данных становится так много, что их уже не удаётся разместить на одном сервере. В таких случаях помогает шардирование — разделение данных на определённое количество частей и хранение полученных частей отдельно друг от друга. Шардирование также помогает обслуживать более высокую нагрузку за счёт разделения потоков на два и более.
Следующий шаг — запуск новых сервисов: когда у компании есть основная специализация, но также она хочет решать и другие бизнес-задачи. Это значит, что появляются новые поиски: медиа, сообществ, людей, товаров — варианты могут быть разными. Проще всего в такой ситуации повторить всё снова несколько раз.
Возможна и альтернативная архитектура, когда разные сервисы разбиваются на маленькие виртуальные единицы и хаотично распределяются по доступным серверам. Маршрутизация от сервиса идёт через балансировщик или прокси, чтобы получать результаты с разных серверов.
Итого
Поиск ВКонтакте сегодня:
6 крупных сервисов;
54 поисковых кластера;
20 миллионов ежедневной аудитории;
70 миллионов поисков в сутки.
Наш поиск помогает пользователям общаться с друзьями, смотреть интересные видео и клипы, слушать музыку, объединяться в сообщества по интересам. Кроме того, мы постоянно улучшаем глобальный поиск, выводя в результатах не только людей и сообщества, но и музыкальные треки и ролики.
Если же у вашего проекта пока не такая большая аудитория и меньше контента, то вы можете использовать описанный в статье опыт для выбора соразмерного решения для поиска. На первых порах будет достаточно средств базы данных или стандартных поисковых движков. Ранжирование, ML и нейросети внедряйте по мере роста функциональных требований. А за свой движок беритесь, только если это ключевая составляющая вашего бизнеса, и за его счёт вы сможете получить конкурентное преимущество.
Примечание: в основе статьи — доклад на HighLoad++. Вы можете посмотреть запись выступления.
А в конце ноября на TechLead Conf расскажу, как масштабируется описанный подход на проектирование любых инженерных систем, — в докладе «Не делай то, чего можно не делать». Stay tuned.