Ответ 1
Вы можете просто запустить свой запрос 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: как часто в документе появляется термин
- idf: как часто этот термин появляется по индексу
- fieldNorm: важность термина, в зависимости от повышения индекса и длины поля
В вашем примере fieldNorm
имеет значение. У вас есть один документ с более низким termFreq
(1 вместо 1.4142135), поскольку этот термин появляется только один раз, но это совпадение более важно из-за длины поля.
Тот факт, что ваше поле является multiValued, не меняет счет. Я предполагаю, что это будет одно и то же с одним полем значений с тем же контентом. Solr работает с точки зрения длины поля и условий, поэтому да, Дэвид Боуи наказан за то, что у него много других токенов, чем у других.:)
UPDATE
Я действительно думаю, что Дэвид Боуи заслуживает его возможности. Как описано выше, значение fieldNorm
имеет значение. Добавьте атрибут omitNorms=true
в поле text_ws
в schema.xml
и reindex. Тот же запрос даст вам следующий результат:
<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>