Вы можете просто выполнить свой запрос q=field_name:David
с помощью debugQuery=on
и посмотреть, что произойдет.
Это результаты (включая оценку через fl=*,score
), отсортированные по score desc
:
<doc>
<float name="score">0.4451987</float>
<str name="id">2</str>
<arr name="text_ws">
<str>David Letterman</str>
</arr>
</doc>
<doc>
<float name="score">0.44072422</float>
<str name="id">3</str>
<arr name="text_ws">
<str>David Hasselhoff</str>
<str>David Michael Hasselhoff</str>
</arr>
</doc>
<doc>
<float name="score">0.314803</float>
<str name="id">1</str>
<arr name="text_ws">
<str>David Bowie</str>
<str>David Robert Jones</str>
<str>Ziggy Stardust</str>
<str>Thin White Duke</str>
</arr>
</doc>
И это объяснение:
<lst name="explain">
<str name="2">
0.4451987 = (MATCH) fieldWeight(text_ws:David in 1), product of: 1.0 = tf(termFreq(text_ws:David)=1) 0.71231794 = idf(docFreq=3, maxDocs=3) 0.625 = fieldNorm(field=text_ws, doc=1)
</str>
<str name="3">
0.44072422 = (MATCH) fieldWeight(text_ws:David in 2), product of: 1.4142135 = tf(termFreq(text_ws:David)=2) 0.71231794 = idf(docFreq=3, maxDocs=3) 0.4375 = fieldNorm(field=text_ws, doc=2)
</str>
<str name="1">
0.314803 = (MATCH) fieldWeight(text_ws:David in 0), product of: 1.4142135 = tf(termFreq(text_ws:David)=2) 0.71231794 = idf(docFreq=3, maxDocs=3) 0.3125 = fieldNorm(field=text_ws, doc=0)
</str>
</lst>
Факторы оценки здесь:
- termFreq : как часто термин появляется вdocument
- idf : как часто термин встречается в индексе
- fieldNorm : важность термина в зависимости от увеличения индекса и полядлина
В вашем примере fieldNorm
имеет значение.У вас есть один документ с меньшим termFreq
(1 вместо 1.4142135), поскольку термин появляется только один раз, но это совпадение более важно из-за длины поля.
Тот факт, что ваше поле является многозначным, не меняет оценку.Я думаю, это было бы то же самое с одним полем значения с тем же содержанием.Solr работает с точки зрения длины поля и сроков, поэтому, да, Дэвид Боуи наказан за то, что у него было намного больше жетонов, чем у других.:)
ОБНОВЛЕНИЕ
Я действительно думаю, что Дэвид Боуи заслуживает его возможности.Как объяснено выше, fieldNorm
имеет значение.Добавьте атрибут omitNorms=true
в свое поле text_ws
в schema.xml
и переиндексируйте.Тот же запрос даст вам следующий результат:
<doc>
<float name="score">1.0073696</float>
<str name="id">1</str>
<arr name="text">
<str>David Bowie</str>
<str>David Robert Jones</str>
<str>Ziggy Stardust</str>
<str>Thin White Duke</str>
</arr>
</doc>
<doc>
<float name="score">1.0073696</float>
<str name="id">3</str>
<arr name="text">
<str>David Hasselhoff</str>
<str>David Michael Hasselhoff</str>
</arr>
</doc>
<doc>
<float name="score">0.71231794</float>
<str name="id">2</str>
<arr name="text">
<str>David Letterman</str>
</arr>
</doc>
Как вы видите, теперь termFreq
выигрывает, а fieldNorm
вообще не учитывается.Вот почему два документа с двумя вхождениями Дэвида находятся на вершине и с одинаковым счетом, несмотря на их разную длину, а более короткий документ с одним совпадением является последним с самым низким показателем.Вот объяснение с debugQuery=on
:
<lst name="explain">
<str name="1">
1.0073696 = (MATCH) fieldWeight(text:David in 0), product of: 1.4142135 = tf(termFreq(text:David)=2) 0.71231794 = idf(docFreq=3, maxDocs=3) 1.0 = fieldNorm(field=text, doc=0)
</str>
<str name="3">
1.0073696 = (MATCH) fieldWeight(text:David in 2), product of: 1.4142135 = tf(termFreq(text:David)=2) 0.71231794 = idf(docFreq=3, maxDocs=3) 1.0 = fieldNorm(field=text, doc=2)
</str>
<str name="2">
0.71231794 = (MATCH) fieldWeight(text:David in 1), product of: 1.0 = tf(termFreq(text:David)=1) 0.71231794 = idf(docFreq=3, maxDocs=3) 1.0 = fieldNorm(field=text, doc=1)
</str>
</lst>