简体   繁体   中英

ElasticSearch: Filter for documents where any value in an array field is not in a list

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?

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]}
                            }
                        }
                    }

                }
            }
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM