elasticsearch 7.10如何赋予文档中较早出现的术语更多的权重

kq0g1dla  于 2021-06-13  发布在  ElasticSearch
关注(0)|答案(1)|浏览(332)

假设我们在一个特定的字段上为术语“cosmopolitan”发出一个查询(确切的类型不相关),并假设结果集包含几个文档,每个文档都正好包含“cosmopolitan”的“k”示例
通过任何适用的机制(boosting、weighting、sorting等),我希望返回结果集,以便考虑文档中“cosmopolitan”的位置,即如果cosmopolitan的平均位置较低(更接近文档的开头),则其排名/得分较高。
我已经研究了不同类型的查询和脚本,但似乎找不到适用于此的内容,这似乎很奇怪,因为对于许多域来说,术语位置可能非常重要。

ecbunoof

ecbunoof1#

如果我们讨论的是任意函数的精确子串 myfield ,我们可以使用排序脚本,从整个字符串长度中减去第一次出现的索引,从而提高早期出现的次数:

{
  "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 Map不是必需的--字段可能有 fielddata: true 设置太多--无论哪种方式,我们都需要访问 myfield 为了让这个脚本工作。
或者,函数得分查询非常适合这里:

{
  "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_mode , weight 等来满足你的需要。
另外,您可能需要对所有子字符串的出现进行加权平均,您可以在这些脚本中这样做。

相关问题