Поиск на крупных платформах: как работает Elasticsearch и что такое Typesense

Разработка ПО
Блог
Поиск на крупных платформах: как работает Elasticsearch и что такое Typesense
Поделиться:


                

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

Почему обычная база данных не справляется с поиском

Реляционные базы данных умеют искать — через оператор LIKE или встроенный полнотекстовый поиск. На таблице в 50 000 строк это работает нормально. При переходе к миллиону записей начинаются проблемы: запрос сканирует всю таблицу, время ответа растет до секунд, а при одновременных обращениях от тысяч пользователей — система ложится.

Дело в архитектуре. SQL-таблица хранит данные строками — для поиска приходится перебирать все подряд. Специализированные поисковые движки хранят данные иначе: каждое слово знает, в каких документах оно встречается. Это называется инвертированным индексом.

Как устроен поиск внутри крупных сервисов — общая архитектура

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

Инвертированный индекс: как это работает на практике

Представьте предметный указатель в конце книги: слово «архитектура» → страницы 12, 47, 203. Инвертированный индекс работает ровно так же, только вместо страниц — идентификаторы документов. При индексировании движок проходит по всем текстам, разбивает их на слова (токены) и строит эту карту.

Запрос «как устроен поиск» превращается в три токена: «как», «устроен», «поиск». Движок находит документы, где есть каждый из них, объединяет списки и ранжирует. Все это занимает миллисекунды — потому что не нужно читать сами документы, только индекс.

Токенизация и нормализация запросов

Токенизатор разбивает фразу на токены по пробелам и знакам препинания. Дальше включается нормализация: стемминг (отсечение окончаний — «кроссовки» → «кроссовк»), лемматизация (приведение к словарной форме), удаление стоп-слов («и», «в», «на»). Это позволяет найти «купить кроссовки» по запросу «кроссовок недорого» — токены пересекаются после нормализации.

Elasticsearch: для чего создан и где применяется

Elasticsearch появился в 2010 году. Shay Banon писал его как более удобную обертку над Apache Lucene — Java-библиотекой полнотекстового поиска, которой к тому времени было уже 10 лет. Lucene мощная, но сложная в настройке. Elasticsearch добавил REST API, горизонтальное масштабирование и простую кластеризацию.

Сегодня Elasticsearch — часть стека ELK (Elasticsearch + Logstash + Kibana). Типичные сценарии: поиск по логам в DevOps, полнотекстовый поиск на сайтах с миллионами документов, аналитика по событиям. Его используют Wikipedia, GitHub, Netflix — там, где объемы данных измеряются терабайтами и нужна горизонтальная масштабируемость.

У Elasticsearch есть и ограничения. JVM-база означает большой footprint по памяти — рабочий кластер стартует от 4–8 ГБ RAM. Настройка маппинга и шардов требует понимания внутренней архитектуры, иначе легко получить медленный кластер или Out Of Memory при пиковых нагрузках.

Как работает поиск в Elasticsearch — от запроса до результата

Цикл обработки запроса состоит из нескольких шагов:

  • Клиент отправляет Query DSL (JSON-запрос) на координирующую ноду кластера
  • Нода рассылает запрос на все шарды, где хранятся документы
  • Каждый шард локально ищет по своему Lucene-индексу и возвращает top-N результатов с оценками
  • Координирующая нода объединяет результаты, финально ранжирует и возвращает клиенту

Ранжирование по умолчанию работает по алгоритму BM25 (Best Match 25) — улучшенный вариант TF-IDF. Он учитывает частоту слова в документе, редкость слова по всему индексу и длину документа. Чем реже слово встречается в коллекции, тем выше его вес при совпадении.

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

Typesense: быстрый поиск для разработчиков без DevOps-нагрузки

Typesense появился в 2016 году. Написан на C++ — не потому что это модно, а потому что цель была конкретной: время ответа менее 50 миллисекунд на любых разумных объемах данных без дополнительной настройки.

Главная особенность — встроенная устойчивость к опечаткам (typo tolerance). Запрос «кросовки» даст те же результаты, что «кроссовки» — движок автоматически ищет варианты в пределах редакционного расстояния. Для e-commerce и поиска по каталогу это критично: пользователи ошибаются, и терять их на опечатке — дорого.

Typesense значительно проще в развертывании, чем Elasticsearch. Один бинарник, минимум конфигурации, есть Typesense Cloud как managed-сервис. Платит за это ограниченной масштабируемостью при терабайтных объемах и менее гибкой системой анализа текста.

Elasticsearch vs Typesense — в чем разница и что выбрать

Параметр

Elasticsearch

Typesense

Год выпуска

2010

2016

Язык реализации

Java (Apache Lucene)

C++

Среднее время ответа

50–200 мс при настройке

< 50 мс из коробки

Typo tolerance

Требует настройки fuzzy

Встроенная, работает по умолчанию

Минимальный RAM

4–8 ГБ для кластера

512 МБ для старта

Масштабируемость

До петабайт (горизонтально)

До сотен ГБ

Сложность настройки

Высокая (маппинг, шарды, JVM)

Низкая (YAML-конфиг)

Сценарий применения

Логи, аналитика, корпоративный поиск

Каталоги, e-commerce, SaaS-поиск

Лицензия

Elastic License 2.0 (с 2021)

Apache 2.0 (open-source)

Если проект — стартап с каталогом до 10 млн документов и нет отдельного DevOps-инженера, Typesense быстрее запустить и дешевле поддерживать. Если нужен анализ логов, сложные агрегации или объемы данных под терабайт — Elasticsearch оправдан, несмотря на сложность.

Другие движки: Meilisearch, Solr, OpenSearch

Meilisearch (2018, написан на Rust) — ближайший конкурент Typesense. Такая же ставка на скорость и простоту, похожая typo tolerance. Разница в деталях: у Meilisearch чуть менее гибкие фасеты, но более простой API. Лицензия MIT делает его популярным в open-source проектах.

Apache Solr существует с 2004 года — старейший из живых. Тоже строится на Lucene, конкурент Elasticsearch в энтерпрайз-сегменте. Богатая экосистема, много документации, но сложнее в оркестрации кластера и менее активное развитие в последние годы.

OpenSearch — форк Elasticsearch 7.10, созданный AWS в 2021 году после смены лицензии Elastic. Функционально почти идентичен ES, но под Apache 2.0. Хороший выбор для тех, кто уже сидит на AWS и хочет полностью открытую лицензию.

FAQ — частые вопросы о поисковых движках

Что такое инвертированный индекс простыми словами?

Словарь наоборот: не «документ → слова», а «слово → документы, где оно встречается». Именно это позволяет искать за миллисекунды по миллионам текстов.

Можно ли использовать Elasticsearch бесплатно?

Да. Базовые функции доступны бесплатно под Elastic License 2.0. Ограничения касаются коммерческого использования в SaaS-продуктах — встроить ES в свой облачный сервис и продавать нельзя без лицензионного соглашения.

Сколько документов выдерживает Typesense?

Несколько сотен миллионов документов — при условии достаточного RAM, так как Typesense держит индекс полностью в памяти. Типовой проект на 5–10 млн товарных карточек работает стабильно на сервере с 8–16 ГБ RAM.

Нужен ли отдельный поисковый движок для небольшого сайта?

До 50 000 документов — скорее нет, встроенный поиск CMS справится. При большем объеме или требованиях к скорости и релевантности — да, стоит выделить под поиск отдельный сервис.

Как поисковый движок обрабатывает русский язык?

Через анализаторы — наборы токенизаторов и фильтров под конкретный язык. Для русского в Elasticsearch есть морфологический анализатор (плагин russian_morphology). Typesense с русским работает, но морфология слабее — стемминг проще, чем полная лемматизация.

Что такое BM25 и почему он лучше TF-IDF?

BM25 — это TF-IDF с двумя поправками: насыщение частоты (дополнительные вхождения слова в длинном документе дают все меньший прирост оценки) и нормализация по длине документа. В результате короткий точный ответ не проигрывает длинной статье только потому, что в ней слово встречается чаще.

Хочешь работать с нами? Отправь свое резюме

Нажимая на кнопку, вы соглашаетесь с Политикой конфиденциальности персональных данных

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