solr多值域的评分

时间:2012-02-13 13:39:29

标签: solr lucene

如果我在Solr中有一个带有多值字段的文档,那么多个值是独立得分还是仅连接并评分为一个大字段?我希望他们能够独立得分。这是我的意思的一个例子:

我有一个文件,其中包含一个人名的字段,同一个人可能有多个名字。名称都是不同的(在某些情况下非常不同),但它们都是同一个人/文件。

第1人: David Bowie,David Robert Jones,Ziggy Stardust,Thin White Duke

第2人: 大卫莱特曼

第3人: David Hasselhoff,David Michael Hasselhoff

如果我要搜索“大卫”,我希望所有这些人都有同样的机会。如果每个名称都是独立评分的,那就好像是这样。如果它们只是作为单个字段进行存储和搜索,David Bowie将会因为拥有更多令牌而受到惩罚。 Solr如何处理这种情况?

2 个答案:

答案 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>

这里的得分因素是:

  • termFreq :术语出现在文档中的频率
  • idf :该字词在索引中出现的频率
  • fieldNorm :该术语的重要性,取决于索引时间提升和字段长度

在您的示例中,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没有任何好处。