Hi, I used exact match for a list of numbers. the output order is not the same as input. I tried multiple methods but there some issues.
mydb is my database, the input is an array of integers to be matched to "my_id" and the output is limited to two fields.
method1:
GET mydb/_search
{
"query": {
"terms": {
"my_id": [1010, 203, 456, 789]
}
},
"script_fields": {
"order_test": {
"script": {
"lang": "painless",
"source": """
Map orderMap = new HashMap();
orderMap.put(1010, 0);
orderMap.put(203, 1);
orderMap.put(456, 2);
orderMap.put(789, 3);
return orderMap.getOrDefault(doc['my_id'].value, 9999);
"""
}
}
},
"_source": ["insdc_accession_id","my_id"]
}
Method2:
GET mydb/_search
{
"query": {
"terms": {
"my_id": [1010, 203, 456, 789]
}
},
"sort": [
{
"_script": {
"type": "number",
"script": {
"lang": "painless",
"source": """
def order = [1010, 203, 456, 789];
return order.indexOf(doc['my_id'].value);
"""
},
"order": "asc"
}
}
],
"_source": ["insdc_accession_id","my_id"]
}
Method3:
GET mydb/_search
{
"query": {
"terms": {
"my_id": [1010, 203, 456, 789]
}
},
"sort": [
{
"_script": {
"type": "number",
"script": {
"lang": "painless",
"source": """
long v = doc['my_id'].value;
if (v == 1010L) { return 0; }
else if (v == 203L) { return 1; }
else if (v == 456L) { return 2; }
else if (v == 789L) { return 3; }
else { return 9999; }
"""
},
"order": "asc"
}
}
],
"_source": ["insdc_accession_id","my_id"]
}
The expected result should be [1010, 203, 456, 789] for my_id,
the result of the first two methods are the same as [203, 456, 789, 1010],
the third method is functional but not easy to implement for a high number of values.
I am looking forward the simplest way to keep the order as it is received.
Thank you