我知道,弹性查询在计算查询检索的文档分数时会考虑字段的长度。字段越短,权重越高(请参见字段长度范数)。
我喜欢这种行为:当我搜索iphone我在更感兴趣iphone 6比Crappy accessories for: iphone 5 iphone 5s iphone 6。
iphone
iphone 6
Crappy 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]]
[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()]]
编辑:我提供了第一个答案,但我希望有一个更好的答案
它看起来像你可以做到这一点使用的字段类型token_count连同field_value_factor功能评分。
token_count
field_value_factor
因此,在字段映射中类似以下内容:
"name": { "type": "string", "fields": { "length": { "type": "token_count", "analyzer": "standard" } } }
这将使用该字段中的令牌数。如果要使用字符数,可以将分析器从standard自定义符号化为将每个字符标记化。
standard
然后在查询中:
"function_score": { ..., "field_value_factor": { "field": "name.length", "modifier": "reciprocal" } }