如何提高 elasticsearch 函数得分中的字段长度范数?
How can I boost the field length norm in elasticsearch function score?
我知道 elasticsearch 在计算查询检索到的文档的分数时会考虑字段的长度。字段越短,权重越高(参见The field-length norm)。
我喜欢这种行为:当我搜索 iphone
时,我对 iphone 6
比 Crappy accessories for: iphone 5 iphone 5s iphone 6
更感兴趣。
现在,我想尝试提升这个东西,假设我想把它的重要性加倍。
我知道可以使用 function score, and I guess that I can achieve what I want via script score 修改乐谱。
我试过像这样向分数添加另一个字段长度范数:
{
"query": {
"function_score": {
"boost_mode": "replace",
"query": {...},
"script_score": {
"script": "_score + norm(doc)"
}
}
}
}
但我失败得很厉害,得到这个错误:[No parser for element [function_score]]
编辑:
我的第一个错误是我没有将函数分数包装在 "query" 中。现在我编辑了上面的代码。我的新错误是
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()]]
编辑:我提供了第一个答案,但我希望有一个更好的答案
我有这样的作品。通过以下内容,我从分数中扣除了我感兴趣的字段的长度。
{
"query": {
"function_score": {
"boost_mode": "replace",
"query": {...},
"script_score": {
"script": "_score - doc['<field_name>'].value.length()"
}
}
}
}
然而,与旧分数相比,我无法控制我减去的这个数字的相对权重。这就是为什么我不接受我的回答:我会等待更好的一段时间。理想情况下,我希望有一种方法可以访问 script_score
中的 field length norm 函数,或者获得等效的结果。
看起来你可以使用 type token_count
together with a field_value_factor
function score.
的字段来实现
所以,在字段映射中是这样的:
"name": {
"type": "string",
"fields": {
"length": {
"type": "token_count",
"analyzer": "standard"
}
}
}
这将使用字段中的标记数。如果你想使用字符数,你可以将分析器从 standard
更改为一个自定义的分析器来标记每个字符。
然后在查询中:
"function_score": {
...,
"field_value_factor": {
"field": "name.length",
"modifier": "reciprocal"
}
}
我知道 elasticsearch 在计算查询检索到的文档的分数时会考虑字段的长度。字段越短,权重越高(参见The field-length norm)。
我喜欢这种行为:当我搜索 iphone
时,我对 iphone 6
比 Crappy accessories for: iphone 5 iphone 5s iphone 6
更感兴趣。
现在,我想尝试提升这个东西,假设我想把它的重要性加倍。
我知道可以使用 function score, and I guess that I can achieve what I want via script score 修改乐谱。
我试过像这样向分数添加另一个字段长度范数:
{
"query": {
"function_score": {
"boost_mode": "replace",
"query": {...},
"script_score": {
"script": "_score + norm(doc)"
}
}
}
}
但我失败得很厉害,得到这个错误:[No parser for element [function_score]]
编辑:
我的第一个错误是我没有将函数分数包装在 "query" 中。现在我编辑了上面的代码。我的新错误是
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()]]
编辑:我提供了第一个答案,但我希望有一个更好的答案
我有这样的作品。通过以下内容,我从分数中扣除了我感兴趣的字段的长度。
{
"query": {
"function_score": {
"boost_mode": "replace",
"query": {...},
"script_score": {
"script": "_score - doc['<field_name>'].value.length()"
}
}
}
}
然而,与旧分数相比,我无法控制我减去的这个数字的相对权重。这就是为什么我不接受我的回答:我会等待更好的一段时间。理想情况下,我希望有一种方法可以访问 script_score
中的 field length norm 函数,或者获得等效的结果。
看起来你可以使用 type token_count
together with a field_value_factor
function score.
所以,在字段映射中是这样的:
"name": {
"type": "string",
"fields": {
"length": {
"type": "token_count",
"analyzer": "standard"
}
}
}
这将使用字段中的标记数。如果你想使用字符数,你可以将分析器从 standard
更改为一个自定义的分析器来标记每个字符。
然后在查询中:
"function_score": {
...,
"field_value_factor": {
"field": "name.length",
"modifier": "reciprocal"
}
}