我的文档中有一个字段,它存储一个整数数组。
Java类:
public class Clazz {
public List<Foo> foo;
public static Foo {
public Integer bar;
public Integer baz;
}
}
映射:
"properties" : {
"foo" : {
"properties" : {
"bar" : {
"type" : "integer"
},
"baz" : {
"type" : "integer"
}
}
}
}
示例文档:
{
id: 1
foo: [
{ bar: 10 },
{ bar: 20 }
]
},
{
id: 2
foo: [
{ bar: 15 }
]
}
现在我想做我的得分。评分函数的值为input
:10
。
评分函数基本上是:&#34; foo.bar
越靠近input
,得分越高。如果foo.bar
低于input
,那么得分只有一半好&#34;
查询:
"function_score" : {
"functions" : [ {
"script_score" : {
"script" : "if(doc['foo.bar'].value >= input) { (input - doc['foo.bar'].value) * 1 } else { (doc['foo.bar'].value - input) * 2 }",
"lang" : "groovy",
"params" : {
"input" : 10
}
}
} ],
"score_mode" : "max",
"boost_mode" : "replace"
}
预期结果:
id 1
应该是第一位的,因为foo.bar
匹配input=10
。
会发生什么:
如果文档只有单个 foo.bar
值,则评分可以正常运行。如果它是一个数组(就像在带有id 1
的文档中那样),Elasticsearch似乎占据了数组中的最后一个值。
查询应该执行的操作:
获得最高分。这就是我使用score_mode: max
的原因。但似乎这只是尊重functions
中的function_score
数组,而不是(正如我预期的那样)函数中可能的分数。
我在某处读过使用doc['foo.bar'].values
(值 s 而不是值),但在这种情况下我不知道如何使用它。
你有什么想法,如何让这个工作?
答案 0 :(得分:3)
使用groovy实现此目的的一种方法如下,即您可以使用值的最大列表方法。
示例:
{
"query": {
"function_score": {
"functions": [
{
"script_score": {
"script": "max_score=doc[\"foo.bar\"].values.max();if(max_score >= input) {return (max_score - input);} else { return (max_score - input) *2;}",
"lang": "groovy",
"params": {
"input": 10
}
}
}
],
"score_mode": "max",
"boost_mode": "replace"
}
}
}