0

I would like to query my elasticsearch index in order to retrieve the documents that don't contain a specific value in an array. For instance, if my query is :

{
    "query": {
        "bool": {
            "must": [
                {
                    "match_all": {}
                }
            ],
            "must_not": [],
            "should": []
        }
    },
    "from": 0,
    "size": 10,
    "sort": [],
    "facets": {}
}

And the dataset :

{
    "took": 1,
    "hits": {
        "total": 1,
        "hits": [
            {
                "_index": "product__1434374235336",
                "_type": "product",
                "_id": "AU33Xeny0K4pKlL-a7sr",
                "_source": {
                    "interdictions": ["S0P","SK3"],
                    "code": "foo"
                }
            },
            {
                "_index": "product__1434374235336",
                "_type": "product",
                "_id": "AU33Xeny0K4pKlL-a7sr",
                "_source": {
                    "interdictions": ["S0P","S2V","SK3"],
                    "code": "bar"
                }
            }
        ]
    }
}

The objective is to exclude each product that contains the "S2V" interdiction. I initially thought of using a missing filter :

{
    "query": {
        "bool": {
            "must": [
                {
                    "match_all": {}
                }
            ],
            "must_not": [],
            "should": []
        }
    },
    "filter": {
        "missing": {
            "terms": {
                "interdictions": [
                    "S2V"
                ]
            }
        }
    },
    "from": 0,
    "size": 10,
    "sort": [],
    "facets": {}
}

But elasticsearch fails to parse the query : QueryParsingException[[product__1434374235336] [missing] filter does not support [interdictions]]; }]",. I then tried with a must_not :

{
    "query": {
        "bool": {
            "must": [
                {
                    "match_all": {}
                }
            ],
            "must_not" : {
                "terms" : {
                    "interdictions" : ["S2V"]
                }
            }
        }
    },
    "from": 0,
    "size": 10
}

But the output is incorrect since it returns a product with the S2V interdictions.

So... What is the correct way to do this ?

Thanks !

1
  • 1
    The answer from @Andrei Stefan make senses. BTW you can use match instead of terms, so the analyzer will be applied for S2V when querying. View more here (Why doesn’t the term query match my document?) : elastic.co/guide/en/elasticsearch/reference/current/… Commented Jun 16, 2015 at 8:01

1 Answer 1

1

Try this (with lowercase value for the terms bool):

{
  "query": {
    "bool": {
      "must": [
        {
          "match_all": {}
        }
      ],
      "must_not": {
        "terms": {
          "interdictions": [
            "s2v"
          ]
        }
      }
    }
  },
  "from": 0,
  "size": 10
}

Most probably, you have an analyzer (maybe the standard default one) that does lower case the terms, so in the ES index the value is indexed as s2v, sk3 etc. And terms doesn't analyze the input value, it's using it as is (in your case with uppercase letters), so it will never match.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.