如果我在Solr中有一个带有多值字段的文档,那么多个值是独立得分还是仅连接并评分为一个大字段?我希望他们能够独立得分。这是我的意思的一个例子:
我有一个文件,其中包含一个人名的字段,同一个人可能有多个名字。名称都是不同的(在某些情况下非常不同),但它们都是同一个人/文件。
第1人: David Bowie,David Robert Jones,Ziggy Stardust,Thin White Duke
第2人: 大卫莱特曼
第3人: David Hasselhoff,David Michael Hasselhoff
如果我要搜索“大卫”,我希望所有这些人都有同样的机会。如果每个名称都是独立评分的,那就好像是这样。如果它们只是作为单个字段进行存储和搜索,David Bowie将会因为拥有更多令牌而受到惩罚。 Solr如何处理这种情况?
答案 0 :(得分:19)
您可以使用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>
这里的得分因素是:
在您的示例中,fieldNorm
有所不同。您有一个较低termFreq
(1而不是1.4142135)的文档,因为该术语只出现一次,但由于字段长度,该匹配更为重要。
您的字段为多值的事实不会改变评分。我想这与具有相同内容的单个值字段相同。 Solr在字段长度和术语方面工作,所以,是的,David Bowie因为拥有比其他人更多的令牌而受到惩罚。 :)
<强>更新强>
我实际上认为大卫鲍伊值得他的机会。如上所述,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
完全没有被考虑在内。这就是为什么带有两个David出现的两个文档在顶部并且具有相同的分数,尽管它们的长度不同,并且只有一个匹配的较短文档是具有最低分数的最后一个。以下是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>
答案 1 :(得分:3)
你可以使用Lucenes SweetSpotSimilarity来定义应该都具有1.0范数的长度平台。只要您正在搜索名称等内容,这可以帮助您处理您的情况.lengthNorm没有任何好处。