我正在尝试在索引上构建自定义分数。分数基于几个标准,比如说(不介意这是否真的相关,这只是一个例子):
我的得分是这样的:对于这三个匹配的标准中的每一个,得分为1.然后,平均这些(即除以所有加权因子的总和),但还有一个额外的伎俩:一个标准不能匹配(即“大小”对于一个项目为空,或者“离家”的距离),那么,我必须排除这个未知的加权因子。
示例:如果item_1匹配所有三个标准,则得分为:
Criterion 1 : 1 (score) * 2 (weight)
Criterion 2 : 1 (score) * 3 (weight)
Criterion 3 : 1 (score) * 1 (weight)
Sum of weight for available criteria : 6
Total : 6/6 = 1 (fairly simple)
如果item_2符合条件1和2但没有评级,我们会排除标准3的权重,得分如下:
Criterion 1 : 1 (score) * 2 (weight)
Criterion 2 : 1 (score) * 3 (weight)
Criterion 3 : not available => 0
Sum of weight for available criteria : 5, as we exclude 3
Total : 5/5 = 1
问题是:我能有效地做到吗?
到目前为止我所拥有的:
{"term" : { "size" < 3 }}
这可以这样:每个函数都是基于过滤器的,得分为1,我们使用boost模式“replace”来替换任何查询结果,并使用“should”来添加个人匹配。
我们将此查询称为sumQuery
:
"{ "bool" : {
"should" : [
{ "function_score" : {
"functions" : [
{
"filter": { "term" : { "size" < 3 }},
}
],
"score_mode": "sum",
"boost_mode": "replace",
"boost": 2
}
// Other criteria
]
}
}
现在,为了计算如何划分这个总和,我只能想到的是构建一个脚本函数,比如说:
sumOfWeights=6d;
if (doc['size'].value == null) sumOfWeights -= 2;
if (doc['ratings'].value == null) sumOfWeights -= 1;
// ...
return _score/sumOfWeights;
使用此函数编写mainQuery
:
"query": {
"function_score": {
"query": **mainQuery**,
"functions" : [ {
"script_score" : {
"script" : **script above**
}
} ]
}
}
这对我来说似乎过于复杂,并且在我的索引上会变得很慢(尤其是脚本部分)并且给出了标准的数量。你有什么(更好的)想法吗?
答案 0 :(得分:0)
requested evolution应该可以缓解这种情况。
涉及:
function_score
的函数中添加查询,从而允许任意组合查询分数function
的分数avg
的某些情况下使weight
组合更好1}}不会被考虑在内选项2几乎提供了问题所需的所有内容,因为一旦您可以访问每个项目的个人分数,您就可以决定将哪一个考虑在内。
选项1允许以不同方式处理事物,例如通过提出计算标准总和的子请求,以及另一个计算权重来除以它。