【问题标题】:Scoring of solr multivalued fieldsolr多值字段的评分
【发布时间】:2012-02-21 03:02:42
【问题描述】:

如果我在 Solr 中有一个包含多值字段的文档,多个值是独立评分还是只是连接起来并作为一个大字段评分?我希望他们是独立得分的。这是我的意思的一个例子:

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

第 1 个人: 大卫鲍伊、大卫罗伯特琼斯、齐格星尘、瘦白公爵

第 2 个人: 大卫莱特曼

第 3 个人: 大卫·哈塞尔霍夫、大卫·迈克尔·哈塞尔霍夫

如果我要搜索“David”,我希望所有这些都具有大致相同的匹配机会。如果每个名字都是独立评分的,情况似乎就是这样。如果它们只是作为单个字段存储和搜索,David Bowie 将因拥有比其他人多得多的令牌而受到惩罚。 Solr 如何处理这种情况?

【问题讨论】:

    标签: solr lucene


    【解决方案1】:

    您可以使用debugQuery=on 运行查询q=field_name:David,看看会发生什么。

    这些是按score desc排序的结果(包括通过fl=*,score的分数):

    <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 在字段长度和术语方面起作用,所以,是的,大卫鲍伊因拥有比其他人多得多的令牌而受到惩罚。 :)

    更新
    我实际上认为大卫鲍伊应该得到他的机会。如上所述,fieldNorm 与众不同。将属性omitNorms=true 添加到schema.xml 中的text_ws 字段并重新索引。同样的查询会给你以下结果:

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

    【讨论】:

    • 感谢详细的分类,这正是我需要知道的。是否有另一种方法可以索引这些数据以使这些名称得到更“公平”的评分?
    • @user605331 看看我更新的答案,我也给了大卫鲍伊一个机会!
    • 省略规范会有所帮助,但这不是一个好的解决方案。人们可能希望将 fieldNorm 考虑在内,但仍然必须使用多值字段。所以我们必须在这两者之间做出决定:(
    【解决方案2】:

    您可以使用 Lucenes SweetSpotSimilarity 来定义所有标准都应为 1.0 的长度平台。只要您正在搜索名称等内容,这可以帮助您解决您的情况。lengthNorm 没有任何好处。

    【讨论】:

    • 这看起来很有希望。虽然它设置在 IndexWriter 级别,而不是针对特定字段,所以如果我有大量其他文本(可能是传记或适合此处示例的内容),那么我也必须使用 SweetSpotSimilarity,对吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多