Reputation: 1625
I have a situation where I have field containing an array of integers. I need to be able to implement a query that filters out documents that contain only a certain set of values in this array.
For example, say I created the following index:
PUT /test/stuff/1
{
"foo": [1,2,3]
}
PUT /test/stuff/2
{
"foo": [2]
}
PUT /test/stuff/3
{
"foo": [1,3]
}
Now I would like to get all documents where "foo" contains any value that is not in [2,4]. I want to have the documents with ids 1 and 3 to be returned. Not that document 1 does contain the value 2
, but also contains other values. A simple must_not
like this will filter out document 1:
POST /test/stuff/_search
{
"query": {
"bool": {
"must" : {
"match_all": {}
},
"filter" : {
"bool": {
"must_not": [
{
"terms" : {"foo" : [2,4]}
}
]
}
}
}
}
}
The above query will only match document 3. Is there a way to rewrite this to also include document 1?
Upvotes: 1
Views: 5195
Reputation: 58
This is doable with a script query, illustrated with painless as follows:
{
"query": {
"bool": {
"must" : {
"match_all": {}
},
"filter" : {
"bool": {
"must": {
"script" : {
"script" : {
"inline" : "for(int i: doc['foo']) { boolean matches = true; for(int j: params.param1){if(i==j) matches = false;} if(matches) return true;} ",
"lang" : "painless",
"params" : { "param1": [2,4]}
}
}
}
}
}
}
}
}
Upvotes: 3