[英]ElasticSearch how to sort by a giving idList
我有一个要查询的参数列表,我想按此参数列表顺序获取结果排序
在 MYSQL 中,它看起来像这样
select * from tableA
where id in (3, 1, 2)
order by field(id, 3, 1, 2)
如何在es中达到同样的效果?
"query":{
"bool":{
"must":{
{"terms":{ "xId" : #[givenIdList] }}
}
}
}
"sort":{how to sort by #[givenIdList]?}
感谢您的任何建议。
这个想法是,给定排序列表[3, 1, 2]
您应该为 3 返回较小的分数,为 1 返回较大的分数,最后为 2 返回最大的分数。您可以考虑的最简单的 function 是从数组元素到其的 function指数。 例如,对于 3,您应该返回 0,对于 1 1 和对于 2 2。
具体来说,您需要一个可能如下所示的 function:
def myList = [3, 1, 2];
// Declares a map literal
Map m= [:];
// Generate from [3, 1, 2] the mapping { 3 = 0.0, 1 = 1.0, 2 = 2.0 }
def i = 0;
for (x in myList) {
m[x] = (double)i++;
}
// Extract the xId from the document
def xId = (int)doc['xId'].value;
// Return the mapped value, e.g., for 3 return 0
return m[xId];
显然,您可以通过直接将 map 作为参数传递给此处报告的脚本来提高性能。
在这种情况下,脚本简化为:
def xId = doc['xId'].value.toString();
return params.m[xId];
索引数据
POST _bulk
{"index": { "_index": "test", "_id": 1}}
{"xId": 1}
{"index": { "_index": "test", "_id": 2}}
{"xId": 2}
{"index": { "_index": "test", "_id": 3}}
{"xId": 3}
{"index": { "_index": "test", "_id": 4}}
{"another_field": "hello"}
使用列表方法的完整示例:
GET test/_search
{
"query": {
"terms": {
"xId": [3, 1, 2]
}
},
"sort": {
"_script": {
"type": "number",
"script": {
"lang": "painless",
"params": {
"list": [3, 1, 2]
},
"source": """
Map m= [:];
def i = 0;
for (x in params.list) {
m[x] = (double)i++;
}
def xId = (int)doc['xId'].value;
m[xId];
"""
},
"order": "asc"
}
}
}
使用 map 方法的完整示例
GET test/_search
{
"sort": {
"_script": {
"type": "number",
"script": {
"lang": "painless",
"params": {
"list": [3, 1, 2],
"map": {
"3": 0.0,
"1": 1.0,
"2": 2.0
}
},
"source": """
def xId = doc['xId'].value.toString();
params.map[xId];
"""
},
"order": "asc"
}
},
"query": {
"terms": {
"xId": [3, 1, 2]
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.