⚠️ Эта страница автоматически переведена, и перевод может быть несовершенным.
blog-post

How to Make xt850 Match xt 850

Кратко

С версии 23.0.0 Manticore может делать так, чтобы запрос xt850 находил xt 850, используя bigram_delimiter вместе с режимами bigram_index , учитывающими цифры.

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

Предположения и проверка

В этой статье мы исходим из того, что:

  • RT-таблицы созданы по SQL‑примерам ровно в том виде, как они показаны
  • используется токенизация по умолчанию, если в примере явно не меняется настройка
  • ASCII‑цифры в названиях моделей, поскольку second_numeric и second_has_digit — режимы, учитывающие цифры, построенные вокруг 0-9

Все SQL‑примеры и ожидаемые результаты в этой статье мы проверили перед публикацией на реальном сервере Manticore 23.0.0, используя новые таблицы, созданные с нуля для каждого сценария.

Проблема не только в xt850

Представьте, что у вас есть каталог с такими товарами:

  • xt 850 action camera
  • iphone 5se battery case
  • canon eos 80d body
  • thinkpad x1 carbon

А теперь представьте, что пользователи ищут так:

  • xt850
  • iphone5se
  • eos80d
  • thinkpadx1

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

Обычно поисковые системы решают это расхождение одним из четырёх способов:

  • индексация префиксов или инфиксов
  • добавление пользовательских правил нормализации
  • дублирование контента в альтернативные нормализованные поля
  • индексация соседних пар токенов и при необходимости хранение склеенных вариантов

Новые возможности работы с биграммами в Manticore — это понятный способ реализовать четвёртый вариант без неудобного дублирования полей.

Базовый случай: почему xt850 не работает по умолчанию

Вот как эта проблема выглядит в самом простом виде:

DROP TABLE IF EXISTS bi_default_demo;

CREATE TABLE bi_default_demo(title text);

INSERT INTO bi_default_demo VALUES
  (1,'xt 850 action camera');

SELECT id, title FROM bi_default_demo WHERE MATCH('xt850');

Ожидаемый результат:

Empty set

Почему это не работает?

Потому что при индексации документ разбивается на два отдельных токена, xt и 850, а запрос приходит как один токен, xt850.

По умолчанию Manticore не предполагает, что:

  • xt850 должен быть разбит на xt + 850
  • или xt + 850 также должно быть доступно для поиска как xt850

Таким образом, это не проблема работы с опечатками и не проблема фразового поиска. Это несоответствие токенизации: индекс видит два токена, а запрос предоставляет один.

Именно этот разрыв и закрывают новые настройки биграмм. Они позволяют Manticore индексировать выбранные соседние пары токенов в форме, которая также может совпадать со склеенными запросами.

Что здесь дают биграммы

bigram_index может помочь и с ускорением фразового поиска , и с сопоставлением названий моделей, но в этой статье мы сосредотачиваемся на проблеме xt 850 vs xt850.

Ключевая идея проста:

  • обнаруживать соседние пары токенов, похожие на названия моделей
  • также сохранять эти пары в склеенной форме
  • позволять запросам вроде xt850, iphone5se или thinkpadx1 находить текст с пробелами

Именно здесь важен bigram_delimiter .

Что важно про bigram_delimiter

bigram_index определяет, какие соседние пары подходят.

bigram_delimiter определяет, в каком виде сохраняются подходящие биграммы:

  • true: только внутренний токен с разделителем
  • none: только склеенный токен, например galaxy24
  • both: обе формы

Практическую разницу проще всего понять по тому, как это влияет на запросы:

  • при true Manticore сохраняет только внутреннюю форму биграммы для оптимизации фраз, но не сохраняет склеенную форму, которую вводит пользователь, поэтому запрос xt850 не будет соответствовать xt 850
  • при none Manticore сохраняет только склеенную форму, так что xt850 может соответствовать xt 850, но для таких пар вы целиком опираетесь именно на это склеенное представление
  • при both Manticore сохраняет и внутреннее представление биграммы, и склеенную форму, поэтому xt850 может соответствовать xt 850 без отказа от обычного поведения фразового поиска

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

Режим 1: second_numeric

bigram_index = second_numeric
bigram_delimiter = both

Этот режим рассчитан на названия моделей, где второй токен состоит только из цифр.

Такое часто встречается в товарных каталогах:

  • xt 850
  • galaxy 24
  • playstation 5
  • pixel 8

Идея проста: пользователи часто ищут такие модели в склеенном виде — xt850, galaxy24 или playstation5, хотя в исходном тексте они записаны с пробелом.

second_numeric сохраняет пару только тогда, когда второй токен состоит исключительно из ASCII‑цифр.

Используйте его, когда:

  • у вас есть поколения продуктов и нумерованные модели
  • пользователи часто убирают пробелы в поиске
  • второй токен обычно состоит только из цифр

Пример

DROP TABLE IF EXISTS bi_second_numeric_demo;

CREATE TABLE bi_second_numeric_demo(title text)
  bigram_index='second_numeric'
  bigram_delimiter='both';

INSERT INTO bi_second_numeric_demo VALUES
  (1,'xt 850 action camera'),
  (2,'galaxy 24 ultra'),
  (3,'playstation 5 slim'),
  (4,'iphone 5se case'),
  (5,'canon eos 80d body'),
  (6,'thinkpad x1 carbon');

Теперь проверим запросы по одному:

SELECT id, title FROM bi_second_numeric_demo WHERE MATCH('xt850');

+------+----------------------+
| id   | title                |
+------+----------------------+
|    1 | xt 850 action camera |
+------+----------------------+
SELECT id, title FROM bi_second_numeric_demo WHERE MATCH('galaxy24');

+------+-----------------+
| id   | title           |
+------+-----------------+
|    2 | galaxy 24 ultra |
+------+-----------------+
SELECT id, title FROM bi_second_numeric_demo WHERE MATCH('playstation5');

+------+--------------------+
| id   | title              |
+------+--------------------+
|    3 | playstation 5 slim |
+------+--------------------+
SELECT id, title FROM bi_second_numeric_demo WHERE MATCH('iphone5se');

Empty set
SELECT id, title FROM bi_second_numeric_demo WHERE MATCH('eos80d');

Empty set
SELECT id, title FROM bi_second_numeric_demo WHERE MATCH('thinkpadx1');

Empty set

На этом граница режима и проходит:

  • 24 и 5 подходят
  • 5se, 80d и x1 не подходят

Режим 2: second_has_digit

bigram_index = second_has_digit
bigram_delimiter = both

Этот режим — более гибкий вариант second_numeric.

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

  • xt 850
  • iphone 5se
  • eos 80d
  • thinkpad x1

Используйте его, когда:

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

Пример

DROP TABLE IF EXISTS bi_second_has_digit_demo;

CREATE TABLE bi_second_has_digit_demo(title text)
  bigram_index='second_has_digit'
  bigram_delimiter='both';

INSERT INTO bi_second_has_digit_demo VALUES
  (1,'xt 850 action camera'),
  (2,'galaxy 24 ultra'),
  (3,'playstation 5 slim'),
  (4,'iphone 5se case'),
  (5,'canon eos 80d body'),
  (6,'thinkpad x1 carbon'),
  (7,'kindle paperwhite signature');

Затем проверьте запросы один за другим:

SELECT id, title FROM bi_second_has_digit_demo WHERE MATCH('xt850');

+------+----------------------+
| id   | title                |
+------+----------------------+
|    1 | xt 850 action camera |
+------+----------------------+
SELECT id, title FROM bi_second_has_digit_demo WHERE MATCH('galaxy24');

+------+-----------------+
| id   | title           |
+------+-----------------+
|    2 | galaxy 24 ultra |
+------+-----------------+
SELECT id, title FROM bi_second_has_digit_demo WHERE MATCH('iphone5se');

+------+---------------------+
| id   | title               |
+------+---------------------+
|    4 | iphone 5se case     |
+------+---------------------+
SELECT id, title FROM bi_second_has_digit_demo WHERE MATCH('eos80d');

+------+---------------------+
| id   | title               |
+------+---------------------+
|    5 | canon eos 80d body  |
+------+---------------------+
SELECT id, title FROM bi_second_has_digit_demo WHERE MATCH('thinkpadx1');

+------+---------------------+
| id   | title               |
+------+---------------------+
|    6 | thinkpad x1 carbon  |
+------+---------------------+
SELECT id, title FROM bi_second_has_digit_demo WHERE MATCH('kindlesignature');

Empty set

Часто это более подходящий вариант для смешанных идентификаторов моделей, потому что в реальных каталогах нередко встречаются формы вроде 5se, 80d или x1, а не только чисто числовые суффиксы вроде 24.

Какой режим выбрать

Если ваша задача в поиске — именно «Как заставить xt850 находить xt 850?», практическое правило такое:

  • используйте second_numeric, когда второй токен состоит только из цифр
  • используйте second_has_digit, когда второй токен может быть смешанным, например 5se, 80d или x1

Есть один практический нюанс: в простом случае это совместимо и с другими настройками обработки текста. xt 850 по‑прежнему совпадает с xt850, когда включены morphology='stem_en' и wordforms.

Но это не значит, что эти настройки будут нормализовывать склеенный запрос за вас. В тестах iphones 5 совпадал с iphones5, но не с iphone5, даже при стемминге или замене iphones -> iphone через wordforms. Коротко: в простом случае xt 850 и xt850 совместимы с morphology и wordforms, но если они для вас важны, отдельно проверьте нужную форму запроса.

Главное

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

Начиная с версии 23.0.0, Manticore даёт встроенный способ справиться с этим несоответствием: bigram_delimiter плюс режимы bigram_index, учитывающие цифры. Это заметно проще, чем дублировать поля или собирать свои пайплайны предобработки.

Если ваша основная проблема — производительность поиска фраз, а не сопоставление склеенных названий моделей, см. How to Speed Up Phrase Search with bigram_index .

Установить Manticore Search

Установить Manticore Search