我有很多包含rate
属性的文档,这是一个包含最小/最大接受率范围的数组。
{ "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] }
}
有没有办法改善范围搜索,提供另类这样的范围?
答案 0 :(得分:0)
你要求的是range
,这隐含着是或否的问题。实际上奇怪的是,除了作为一个助推器之外,甚至比其他任何东西都要得分(例如:如果它有,然后提高分数,但如果它没有它,那就没关系)。因此,range
查询趋势最适合在过滤器上下文中使用。
"query": {
"bool": {
"filter": [
{
"range": {
"rate": { "gte": 100, "lte": 500 }
}
}
]
}
}
(语法假设ES 2.0)
这对你没有帮助,但这是你做这个请求的更好方法。
至于您要问的内容,您希望根据文档中的原始值进行加权。这是 less 直接向前,因为值是一个数组,其值可能超出范围而且它不是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(改为使用基于文件的脚本),但上面的方法可行。