календарь
летний code-календарь
летний code
1-ый день уже в проде!
Содержание

С вас вопросы, с нас ответы. Часть 13

Отвечаем на популярные вопросы про elastic search и поисковые системы
Консультирует:
Степан Ляхов, TeamLead в Россельхозбанк

1. Как устроены поисковые системы под капотом?

Если сильно упростить, то любая поисковая система состоит из четырёх частей:
Crawler → Indexer → Search Index → Search API

Crawler отвечает за сбор данных. Он скачивает документы, страницы или товары и сохраняет их в хранилище. Например, Google обходит интернет, а маркетплейс индексирует карточки товаров.

После этого в работу вступает Indexer. Его задача — подготовить документы к поиску. Он извлекает текст, удаляет HTML, разбивает текст на слова и создаёт специальную структуру данных — инвертированный индекс.

Это, пожалуй, самая важная часть поисковой системы. Вместо того чтобы хранить:
Документ → слова
поисковик хранит:
Слово → документы
Например:
elasticsearch → [1, 7]
search → [1, 2, 5, 7]
Благодаря этому не нужно читать все документы при каждом запросе. Система сразу знает, в каких документах встречается нужное слово.

Когда пользователь выполняет запрос, Search API обращается к индексу, получает список кандидатов и запускает ранжирование. Именно здесь используется BM25 или ML-модели, которые пытаются ответить на вопрос: «Какие документы наиболее полезны пользователю?»

На практике современные поисковые системы выглядят ещё сложнее. Появляются:
  • кеши;
  • сервисы подсказок;
  • ML ранжирование;
  • векторный поиск;
  • A/B тестирование;
  • системы сбора метрик.

Но фундамент остаётся тем же.

Сначала данные собираются, затем индексируются, после чего поисковая система очень быстро находит кандидатов и ранжирует их. По большому счёту именно так устроены Google, Wikipedia Search, маркетплейсы и большинство современных поисковых систем. Разница между ними обычно не в принципах работы, а в масштабе.

2. Что происходит после того, как пользователь вводит поисковый запрос?

На первый взгляд кажется, что всё происходит мгновенно — пользователь вводит distributed systems и уже через несколько десятков миллисекунд получает результат. Но за это время поисковая система выполняет несколько этапов.

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

Например: cars может превратиться в car automobile.

После этого начинается поиск кандидатов.

Поисковая система обращается к инвертированному индексу и находит все документы, в которых встречаются слова из запроса. Это может быть:
  • тысяча документов;
  • сто тысяч документов;
  • миллион документов.

Очевидно, показывать пользователю миллион результатов бессмысленно.
Поэтому следующий этап — ранжирование. Для каждого документа вычисляется score — оценка релевантности. В Elasticsearch по умолчанию для этого используется BM25. Алгоритм учитывает:
  • как часто слово встречается в документе;
  • насколько это слово редкое;
  • насколько длинный документ.

В результате документы сортируются по score:
  • Distributed Computing — 15.3
  • Distributed Systems — 13.8
  • Cluster Computing — 8.7

После этого Search API возвращает пользователю только верхнюю часть списка — например, первые 10 результатов.

Если говорить о современных поисковых системах, то всё становится ещё интереснее. Часто после BM25 запускается второй этап ранжирования:
  • ML модели;
  • CatBoost;
  • нейронные сети;
  • векторный поиск.

То есть BM25 сначала находит несколько сотен кандидатов, а ML выбирает лучшие из них.

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

3. Чем векторный поиск отличается от полнотекстового?

Документ:
how search engines work
Полнотекстовый поиск попытается найти документы, в которых встречаются слова:
  • how
  • search
  • engines
  • work

Чем больше совпадений и чем они важнее, тем выше документ окажется в выдаче.
Это очень эффективный подход. Именно так работают BM25, Elasticsearch и большинство классических поисковых систем. Но у него есть ограничение.

Представим, что существует статья:
Information Retrieval
В ней может вообще не быть слов:
how search engines work
Хотя по смыслу она идеально подходит пользователю.

Полнотекстовый поиск такую статью часто не найдёт или поместит очень низко.
Здесь появляется векторный поиск — он работает иначе. Сначала текст преобразуется в числовой вектор — embedding. Например:
How search engines work
превращается в:
[0.12, -0.45, 0.91, ...]
Документ:
Information Retrieval
тоже превращается в вектор:
[0.14, -0.42, 0.88, ...]
Если два вектора находятся рядом в многомерном пространстве, значит тексты похожи по смыслу.

Во время поиска система не ищет совпадения слов — она ищет ближайшие векторы.

Поэтому запрос:
how search engines work
может вернуть:
  • Search Engine;
  • Information Retrieval;
  • Apache Lucene;
  • Elasticsearch.

Даже если точных совпадений слов в документах нет.

Возникает логичный вопрос: означает ли это, что векторный поиск полностью заменит полнотекстовый? Скорее нет.

У обоих подходов есть сильные стороны.

Полнотекстовый поиск:
  • быстрый;
  • хорошо работает с точными запросами;
  • умеет учитывать важность полей;
  • отлично масштабируется.

Векторный поиск:
  • понимает смысл;
  • находит похожие документы;
  • работает с естественным языком;
  • является основой RAG и AI-поиска.

Поэтому сегодня всё чаще используют гибридный подход.
Сначала BM25 находит документы по словам. Затем векторный поиск переупорядочивает результаты с учётом смысла.

Именно так работают многие современные AI Search системы.

Не BM25 против Embeddings. А BM25 вместе с Embeddings.

задай вопрос, а мы ответим

другие статьи