【问题标题】:Elasticsearch 7.10 How to give more weight to terms that appear earlier in a documentElasticsearch 7.10 如何赋予文档中较早出现的术语更多的权重
【发布时间】:2020-12-20 03:17:34
【问题描述】:

假设我们在特定字段上针对术语“cosmopolitan”发出查询(确切的类型不相关),并假设结果集包含多个文档,每个文档都包含“k”个实例国际化。”

通过任何适用的机制(提升、加权、排序等),我希望返回的结果集考虑到文档中“cosmopolitan”的位置,即如果 cosmopolitan 的平均位置是较低(更接近文档的开头),则其排名/分数较高。

我研究了不同类型的查询和脚本,但似乎找不到适用于此的东西,这似乎很奇怪,因为对于许多领域来说,术语位置可能非常重要。

【问题讨论】:

    标签: elasticsearch lucene


    【解决方案1】:

    如果我们谈论的是任意 myfield 的确切子字符串,我们可以使用 sorting script 从整个字符串长度中减去第一次出现的索引,从而提高更早出现的次数:

    {
      "query": { ... },
      "sort": [
        {
          "_script": {
            "script": {
              "params": {
                "substr_value": "cosmopolitan"
              },
              "source": """
                def fieldval = doc['myfield.keyword'].value;
                def indexof = fieldval.indexOf(params.substr_value);
                return indexof == -1 ? _score : _score + (fieldval.length() - indexof)
              """
            },
            "type": "number",
            "order": "desc"
          }
        }
      ]
    }
    

    .keyword 映射不是必需的——该字段也可以有fielddata: true 设置——无论哪种方式,我们都需要访问myfield 的原始值才能使此脚本工作.


    或者,function score query 非常适合这里:

    {
      "query": {
        "function_score": {
          "query": {
            "match": {
              "myfield": "cosmopolitan"
            }
          },
          "script_score": {
            
            "script": {
              "params": {
                "substr_value": "cosmopolitan"
              },
              "source": """
                def fieldval = doc['myfield.keyword'].value;
                def indexof = fieldval.indexOf(params.substr_value);
                return indexof == -1 ? _score : (fieldval.length() - indexof)
              """
            }
          },
          "boost_mode": "sum"
        }
      }
    }
    

    您可以调整其参数,如boost_modeweight 等以满足您的需求。

    此外,您可能希望对所有出现的子字符串进行加权平均,您可以在这些脚本中执行此操作。

    【讨论】:

    • 谢谢,这非常有帮助。我真的很感激。
    • 很好,很高兴听到这个消息!嘿,我正在写一本关于 Elasticsearch 的手册,想hear your input。干杯!
    • 注意:除非在请求的顶层将 track_scores 设置为 true,否则排序上下文脚本的 _score 将始终为 0,因为 ES 不会费心计算分数(它很昂贵而且 ES假设你无论如何都要覆盖它)。
    猜你喜欢
    • 2019-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-13
    • 1970-01-01
    • 1970-01-01
    • 2017-11-20
    相关资源
    最近更新 更多