一尘不染

如何提高Elasticsearch函数得分的字段长度范数?

elasticsearch

我知道,弹性查询在计算查询检索的文档分数时会考虑字段的长度。字段越短,权重越高(请参见字段长度范数)。

我喜欢这种行为:当我搜索iphone我在更感兴趣iphone 6Crappy accessories for: iphone 5 iphone 5s iphone 6

现在,我想尝试增强这些功能,比方说,我想使其重要性加倍。

我知道可以使用功能分数来修改分数,并且我想我可以通过脚本分数来实现我想要的。

我试图像这样向得分添加另一个字段长度范数:

    {
     "query": {
       "function_score": {
         "boost_mode": "replace",
         "query": {...},
         "script_score": {
             "script": "_score + norm(doc)"
         }
       }
     }
   }

但是我失败很严重,得到了这个错误: [No parser for element [function_score]]

编辑:

我的第一个错误是我没有将功能分数包装在“查询”中。现在,我编辑了上面的代码。我的新错误说

GroovyScriptExecutionException[MissingMethodException
[No signature of method: Script5.norm() is applicable for argument types:
(org.elasticsearch.search.lookup.DocLookup) values: 
[<org.elasticsearch.search.lookup.DocLookup@2c935f6f>]
Possible solutions: notify(), wait(), run(), run(), dump(), any()]]

编辑:我提供了第一个答案,但我希望有一个更好的答案


阅读 249

收藏
2020-06-22

共1个答案

一尘不染

它看起来像你可以做到这一点使用的字段类型token_count连同field_value_factor功能评分

因此,在字段映射中类似以下内容:

"name": { 
  "type": "string",
  "fields": {
    "length": { 
      "type":     "token_count",
      "analyzer": "standard"
    }
  }
}

这将使用该字段中的令牌数。如果要使用字符数,可以将分析器从standard自定义符号化为将每个字符标记化。

然后在查询中:

"function_score": {
  ...,
  "field_value_factor": {
    "field": "name.length",
    "modifier": "reciprocal"
  }
}
2020-06-22