Верхнеуровный принцип работы полнотекстового поиска



Представим у нас магазин товаров, товар описывается тремя полями

{

"id": 17

"name": "big black box",

"type": "box_type"

}




Мы хотим уметь полнотекстово поискать по названию, а также пофильтровать товары по типу



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



1. Берем поле name

2. Бьем исходное имя на токены: ["big", "black", "box"]

3. Добавляем инфу, что токены "big", "black" и "box" встречаются в документе 17



Обратный будет представлять собой мапку token -> [document_id] и для поля name будет выглядить так:

{

"big": [17],

"black": [17],

"box": [17]

}




Для остальных индексируемых полей строим аналогично



---



Загрузив несколько документов, получится примерно такое:



Для поля name:

{

"big": [17, 23],

"black": [15, 17, 29],

"box": [17, 18, 22],

"ball": [13, 21],

"small: [13, 29]",

"white: [1, 5]"

}




Для поля type:

{

"box_type": [17, 18, 22],

"ball_type": [13, 21]

}




---



И наконец, чтобы сделать поиск name ~ "small" and type = ball_type, нужно



1. Посмотреть в обратный индекс name на токен small: получим документы [13, 29]

2. Посмотреть в обратный индекс type на токен ball_type: получим документы [13, 21]

3. Пересечь выборки: получим документы [13]



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



Покажите реакцией 👍, если нужно еще постов на тему поиска