Оценка Solr не упорядочивает результаты по проценту совпадения

#solr

#solr

Вопрос:

Я использую solr для поиска по списку имен и использую ngrams для учета частичного сопоставления строк. Если у меня есть имена «Роуз», «Розен», «Розенберг» и «Розенталь», я бы ожидал, что ответит запрос «Роуз»:

 Rose
Rosen
Rosenberg
Rosenthal
 

Но то, что я получаю, это:

 Rosenberg
Rosenthal
Rose
Rosen
 

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

 Rose
Rosenberg
Rosenthal
Rosen
 

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

Ответ №1:

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

Токен — это «форма» слова, фильтр ngram будет генерировать несколько токенов из слова, таких как ro , ros и rose . Поскольку все слова соответствуют одному и тому же токену rose , они получают одинаковую оценку.

Способ решить эту проблему — иметь два поля — одно для точного совпадения и одно для полей ngram, затем по-разному взвешивать эти поля в qf (если используется (e) dismax). Таким образом, точное попадание будет способствовать большему количеству очков.

Ваш первый пример будет достигнут путем упорядочения по алфавитному порядку сортировки сам по себе (поскольку все слова будут иметь одинаковый префикс, это может быть то, что вы хотите).

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

Например, если ваше поле равно name , вы можете добавить поле name_length как целое число, а затем добавить это поле в свой документ при выполнении добавления:

 document.addField("name", name);
document.addField("name_length", name.length()); // or len(name) in python, etc.
 

Как именно вы это делаете, зависит от того, как вы индексируете содержимое. Вы также можете сделать это в цепочке обновлений в Solr, например, с помощью Javascript в StatelessScriptUpdateProcessor. Ручной метод может быть быстрее и проще в реализации, но цепочка обновлений будет доступна независимо от того, откуда происходит операция индексирования (поэтому, если вы индексируете из многих местоположений / кодовых баз и т. Д., Это может быть полезно для оценки).

Комментарии:

1. Мне нравится идея сортировки по длине токена. Как именно я должен индексировать значение индексированного содержимого?

2. @user3688241 Я добавил пример к своему ответу.

Ответ №2:

Способ решить эту проблему — иметь два поля — одно для точного совпадения и одно для полей ngram, затем по-разному взвешивать эти поля в qf (при использовании (e) dismax). Таким образом, точное попадание будет способствовать большему количеству очков.

Это работает, если я использую то же поле для ngram