Как работает поиск? (объясняем "на пальцах")
Пошагово: что происходит, когда вы отправляете запрос
- Вы отправляете запрос в 1С
Например, оператор вводит "блот м16 цынк" (с двумя опечатками). - 1С вызывает сервис
POST /find {"items":[{"name":"блот м16 цынк"}]} - Сервис исправляет опечатки (если включено)
"блот" → "болт" (расстояние Левенштейна)
"цынк" → "цинк" - Сервис приводит слова к нормальной форме
"болты", "болтом", "болтов" → "болт". Это называется стемминг. - Применяются синонимы
Если в конфиге есть синоним "цинк" → "оцинкованный", сервис ищет оба варианта. - Поиск в индексе
Сервис быстро находит все товары, которые содержат "болт", "м16", "оцинкованный". - Ранжирование (сортировка по релевантности)
Сервис считает для каждого товара score — число от 0 до 1, где 1 — идеальное совпадение. Товары, совпавшие с запросом по большему числу слов, получают более высокий score и поднимаются выше в списке. Это настраивается параметромsearch.weights.coverage_boost_per_token. - Фильтрация по порогам
Сервис находит максимальный score среди кандидатов и отбрасывает товары, у которых score нижеmax_score × auto_match_threshold(по умолчанию 0.85). Также учитывается абсолютный минимумabsolute_min_score. Порог работает одинаково для BM25, эмбеддинг и гибридных стратегий. - Ответ сервиса
Сервис возвращает JSON с найденными товарами, их score и способом совпадения. - 1С показывает результат оператору
"Возможно, вы имели в виду Болт М16х60 оцинкованный?"
Что такое score и как его понимать
Score — это число от 0 до 1, которое показывает, насколько найденный товар похож на ваш запрос.
| Значение score | Что значит | Что делать в 1С |
|---|---|---|
| 1.0 | Идеальное совпадение (тот же GUID или штрихкод) | Автоматически использовать — это точно тот же товар |
| 0.90 - 0.99 | Почти точно тот же товар (отличается только незначительно) | Показать оператору: "Скорее всего, это он" |
| 0.75 - 0.89 | Похоже, но не уверены | Показать список вариантов — пусть оператор выберет |
| < 0.75 | Слабое совпадение | Не показывать — создать новый товар |
- Если сервис часто предлагает неверные товары → увеличьте
auto_match_thresholdдо 0.90-0.92 - Если сервис часто ничего не находит (хотя товар есть) → уменьшите
auto_match_thresholdдо 0.75-0.80 - Начните с 0.85 — это баланс для большинства баз
Три уровня поиска (от простого к сложному)
- Точные совпадения (мгновенно, 1-2 мс)
Если вы ищете поid,barcode,codeилиart— сервис сначала проверяет их. Нашел → сразу возвращает результат. Дальше даже не ищет. - N-gram поиск (для коротких запросов, 2-5 мс)
Если вы ищете "перф", а в базе "Перфоратор". Обычный поиск не находит, потому что "перф" слишком короткий. N-gram разбивает "Перфоратор" на части: "Пер", "Перф", "Перфо", "Перфор" — и находит по "Перф". Настраивается вsearch.edge_ngram. - Нечеткий поиск (fuzzy, 3-10 мс)
Если точного совпадения нет, сервис ищет с учетом опечаток, разных форм слов и синонимов. Использует расстояние Дамерау-Левенштейна — алгоритм, который считает, сколько операций (замена, вставка, удаление или перестановка соседних символов) нужно, чтобы слово совпало. "блот" → "болт" (перестановка соседних букв) — найдет. "блооот" → "болт" (2 операции) — тоже найдет, если разрешено.
Как синонимы улучшают поиск
Синонимы — это слова, которые считаются одинаковыми при поиске. Например:
- "цинк" = "оцинкованный" = "zn" = "zinc"
- "нерж" = "нержавеющий" = "stainless" = "a2"
# Добавляем синонимы через API
curl -X POST http://localhost:8080/synonyms \
-H "Content-Type: application/json" \
-d '{"items":[
{"word":"цинк","expansions":["оцинкованный","zn","zinc"]},
{"word":"нерж","expansions":["нержавеющий","stainless","a2"]}
]}'
# Тот же запрос через CLI
sku-cli synonyms add --word "цинк" --expansions "оцинкованный,zn,zinc"
После добавления синонимов запрос "болт м16 цинк" найдет "Болт М16х60 оцинкованный" с высоким score.
- Сервис сам анализирует ваши действия и предлагает синонимы через
GET /admin/learn(PRO only) - Вы можете добавлять вручную через API или CLI
- Синонимы применяются мгновенно, перезапуск сервиса не нужен
Пример из реальной жизни
Запрос оператора: "блот м16 цынк" (с двумя опечатками)
Что делает сервис:
- Исправляет опечатки: "блот" → "болт", "цынк" → "цинк"
- Применяет синонимы: "цинк" → "оцинкованный"
- Ищет в индексе: товары, содержащие "болт", "м16", "оцинкованный"
- Находит "Болт М16х60 оцинкованный"
- Считает score: 0.94 (очень похоже)
- Возвращает результат
{
"matches": [{
"name_out": "Болт М16х60 оцинкованный ГОСТ 7798-70",
"score": 0.94,
"matched_by": "fuzzy_text"
}]
}
Оператор в 1С видит: "Возможно, вы имели в виду Болт М16х60 оцинкованный? Нажмите 'Да' чтобы использовать существующий товар."
Поля type и ref: фильтр по типу и прямая ссылка на объект 1С
Помимо id, сервис поддерживает два поля, которые упрощают интеграцию с 1С:
ref— сериализованная ссылка 1С (например, результатЗначениеВСтрокуВнутр()). Сервис хранит ее как есть и возвращает в ответе, а поиск по ней — точный.type— тип объекта (например,Справочник.Номенклатура). Позволяет ограничить поиск одним классом объектов или комбинировать сart,barcode,code.
Оба поля участвуют в exact-поиске и работают даже с пустым name.
# Поиск по ref
curl -X POST http://localhost:8080/find \
-H "Content-Type: application/json" \
-d '{"items":[{"name":"","ref":"e1cib/data/Справочник.Номенклатура?ref=a1b2c3d4e5f6..."}]}'
# Тот же запрос через CLI
sku-cli search --ref "e1cib/data/Справочник.Номенклатура?ref=a1b2c3d4e5f6..."
# Поиск с фильтром по type
curl -X POST http://localhost:8080/find \
-H "Content-Type: application/json" \
-d '{"items":[{"name":"болт","type":"Справочник.Номенклатура"}]}'
# Тот же запрос через CLI
sku-cli search "болт" --type "Справочник.Номенклатура"
Транслитерация и неправильная раскладка
Если в конфиге включено search.transliteration_enabled = true, сервис автоматически понимает запросы, набранные не в той раскладке или латиницей.
# «Домик в деревне», набрано на русской раскладке как латиница
curl -X POST http://localhost:8080/find \
-H "Content-Type: application/json" \
-d '{"items":[{"name":"ljvbr d lthtdyt"}]}'
# Та же фраза латиницей
curl -X POST http://localhost:8080/find \
-H "Content-Type: application/json" \
-d '{"items":[{"name":"domik v derevne"}]}'
# Тот же запрос через CLI
sku-cli search "ljvbr d lthtdyt"
sku-cli search "domik v derevne"
Сервис размножает каждый токен запроса на возможные варианты (исходный, исправленная раскладка, транслитерация) и ищет по всем сразу. Работает для кириллицы и латиницы.
search.transliteration_threshold (по умолчанию 0.35). Уменьшите порог, если сервис слишком редко срабатывает на транслит; увеличьте, если появляются ложные срабатывания.
Если включены эмбеддинги (PRO only), сервис может искать товары по смыслу, а не только по словам.
Например: "шуруповерт" найдет "дрель-шуруповерт" и "винтоверт", даже если этих слов нет в запросе. Векторы "понимают", что эти слова означают похожие инструменты.