Elasticsearch:如何根据最大/最小值的数组得分范围查询
问题描述:
我有很多包含rate
属性的文档,它是一个包含可接受比率的最小/最大范围的数组。Elasticsearch:如何根据最大/最小值的数组得分范围查询
{ "rate": [250, 700] }
我现在想执行提供了另一种范围查询,例如:
{
"bool": {
"must": [
"range": {
"rate": { "from": 100, "to": 500 }
}
]
}
}
这工作正常,并始终返回在范围内设置的值的至少一个值是什么我想要。
但是,对于所有结果,分数是相同的。无论文档中的值是否与文档上的值相同,或者只是碰到了几个数字的范围都没关系。如下图所示:
{
"_id": "one",
"_score": 1",
"_source": { "rate": [250,750] }
},
{
"_id": "two",
"_score": 1",
"_source": { "rate": [200,350] }
},
{
"_id": "three",
"_score": 1",
"_source": { "rate": [500,750] }
}
有什么办法可以改善范围搜索提供另一个范围吗?
答
您要求的是range
,这是隐含的是或否的问题。实际上,除了作为一种助推器之外,甚至还有可能超过其他任何东西都难以对付它(例如:如果有,那么提高分数,但如果它没有,那么没关系)。因此,range
查询趋向最好在过滤器上下文中使用。
"query": {
"bool": {
"filter": [
{
"range": {
"rate": { "gte": 100, "lte": 500 }
}
}
]
}
}
(语法假设ES 2.0)
这并不能真正帮助你,但它是更好的方式来做到这一点,你正在做的请求。
至于你在问什么,你想根据文档中的原始值进行加权。这是很多减去直接,因为该值是一个数组,其值可能超出范围,它不是一个nested
对象,所以它总是被视为一个数组(这意味着您需要手动重新排除忽略结果)。
完全自定义评分需要脚本(本地或其他),这可以通过脚本评分轻松完成。
如果该值与文档上的值相同,或者只是碰到少量数字的范围,则无关紧要。
我实际上并没有明白第一部分的意思:你想让单个比赛“重量”减少还是更多?距离边缘的距离是否重要?只是匹配很重要?
我会认为更多的比赛是更好的,无论在哪里,他们的范围不同的情况:
{
"query": {
"bool": {
"must": {
"function_score": {
"functions": [
{
"script_score": {
"script": {
"inline": "doc['rate'].values.findAll { it >= gte && it <= lte }.size()",
"lang": "groovy",
"params": {
"gte": 100,
"lte": 500
}
}
}
}
],
"boost_mode": "replace"
}
},
"filter": [
{
"range": {
"rate": {
"gte": 100,
"lte": 500
}
}
}
]
}
}
}
你应该not be using inline Groovy scripts in production(根据使用的文件脚本代替),但上面会工作。
谢谢,@pickypg,我实际上已经忘记了当我问这个问题(现在修复)时添加了范围查询。不幸的是,当我使用AWS ES服务时,我无法访问groovy。你会想到其他任何可以使它工作的想法吗?如果有帮助,我可以对数据进行不同的建模,但是我发现像'rate_from'和'rate_to'这样的单独值更加复杂。这个想法是,它与范围内的某个区域匹配得越多,或者评分越高(即提供100,500个输入时,100,500个输入将是100%匹配,而400,700则不是那么多。 – zanona