Новый ответ
Я оставляю старый ответ ниже, так как он может быть полезен для других людей.В вашем случае вы хотите отфильтровать документы, которые не совпадают, а не только пометить их.Итак, следующий запрос даст вам то, что вы ожидаете, то есть только первый документ:
POST test/_search
{
"query": {
"script": {
"script": {
"source": """
// copy the doc values into a temporary list
def tmp = new ArrayList(doc.Numbers.values);
// remove all ids from the params
tmp.removeIf(n -> params.ids.contains((int)n));
// return true if the array still contains ids, false if not
return tmp.size() > 0;
""",
"params": {
"ids": [
1,
2,
4,
5
]
}
}
}
}
}
Старый ответ
Один из способов решить эту проблему - использоватьПоле скрипта, которое будет возвращать true или false в зависимости от вашего состояния:
POST test/_search
{
"_source": true,
"script_fields": {
"not_present": {
"script": {
"source": """
// copy the numbers array
def tmp = params._source.Numbers;
// remove all ids from the params
tmp.removeIf(n -> params.ids.contains(n));
// return true if the array still contains data, false if not
return tmp.length > 0;
""",
"params": {
"ids": [ 1, 2, 4, 5 ]
}
}
}
}
}
Результат будет выглядеть следующим образом:
"hits" : {
"total" : 2,
"max_score" : 1.0,
"hits" : [
{
"_index" : "test",
"_type" : "doc",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"Id" : 2,
"Numbers" : [
4,
5
]
},
"fields" : {
"not_present" : [
false <--- you don't want this doc
]
}
},
{
"_index" : "test",
"_type" : "doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"Id" : 1,
"Numbers" : [
1,
2,
3
]
},
"fields" : {
"not_present" : [
true <--- you want this one, though
]
}
}
]
}
}