Теория
Как вы сказали, запрос диапазона не будет работать здесь для подсчета очков... но это все же хороший способ отфильтровать исходный индекс.
После того, как индекс отфильтрован (или нет) с помощью некоторого базового запроса, мы можем применить пользовательскую оценку.
Вот некоторый общий пример того, как реализовать пользовательскую оценку: http://spykem.blogspot.com/2013/06/plug-in-external-score-to-solr.html
При реализации пользовательской сортировки — CustomScoreProvider может получить следующие параметры:
- Шаг значения - шаг для снижения оценки
- Шаг оценки - снижайте оценку на это значение всякий раз, когда происходит «шаг значения».
- Максимальная дополнительная оценка — «идеальное совпадение» будет иметь эту оценку в дополнение к собственной оценке (из регулярного поискового запроса), неидеальные совпадения будут иметь пониженное (неотрицательное) значение.
Дополнительный балл будет снижаться на «Шаг оценки» каждый раз, когда расстояние между значением поля и значением запроса будет увеличиваться на «Шаг значения», начиная с «Максимального дополнительного балла» и до тех пор, пока не достигнет нуля.
Дополнительная формула подсчета очков будет выглядеть примерно так (пока не достигнет нуля):
Max additional score - ((|fieldValue - queryValue| / Value Step ) * Score Step)
Пример
Так, например, имея следующие настройки:
- Шаг значения = 0,1
- Шаг оценки = 0,01
- Максимальный дополнительный балл = 1
со следующими значениями индекса для некоторого поля (например, проницаемость):
- 3 (для документа 1)
- 5 (для документа 2)
- 6 (для документа 3)
- 7 (для документа 4)
- 99999999 (для документа 5)
и если исходный поисковый запрос выглядит так:
q={!nearestParser valueStep=0.1 scoreStep=0.01 maxStep=1}permeability:5
Затем результат будет выглядеть так (при условии, что начальная оценка одинакова (1) для всех документов)
- doc2 (с оценкой - 2,0)
- doc3 (с оценкой - 1,9)
- doc1 (с оценкой - 1,8)
- doc4 (с оценкой - 1,8)
- doc5 (с оценкой - 1)
Заключение:
- Doc2 будет иметь лучший результат, так как это идеальное совпадение
- Doc3 будет вторым, так как он максимально близок (без идеального совпадения) к предпочитаемому входу (и в пределах досягаемости)
- Doc1 и doc4 будут иметь одинаковую оценку, так как они оба находятся на одинаковом расстоянии от исходного поискового запроса.
- Doc5 будет иметь первоначальный балл, так как он выходит за рамки диапазона, чтобы считаться «похожим».
Я постараюсь привести какой-нибудь практический пример, но, поскольку это займет некоторое время, я думаю, что сейчас будет лучше ответить с идеей.
Другое возможное решение
Прочитав о NumericRangeQuery, я также идея об использовании структуры поля Trie * (точнее, использовать ее способность эффективно обрабатывать числовой диапазон поиска), чтобы найти самое ближайшее значение из индекса... но пока не понял, как это сделать.
Это потенциально может быть намного более производительным, хотя и намного более сложным... и все еще есть шанс, что структура Trie* не сможет справиться с такой операцией...
person
rchukh
schedule
19.12.2013