elasticsearchbooleanquery

How to write a bool query of "(A & B) | C" condition in elasticsearch


Following this question: bool query - must and should on same level, what does it means? I wonder how can I achieve a simple logical query in elasticsearch using the bool query: (A & B) | C where A, B, and C are all match queries needed to be combined with bool.

If I understand correctly, the should clause in the bool query only makes those results' scores be higher. If that's the case, how can I achieve an "OR" relation?

Let's say A, B, and C are all number ranges so something like (pseudo code):

(x >= 4 & x<=6) | x=2

From this, I expect to get the potential result set of 2,4,5,6 (="give me all numbers between 4 and 6 inclusive, but 2 is also fine") - but this is not the case since if "&" means "must" - then the "and" and the "or" parts contradict each other (that's what I understood from people who know elasticsearch more than I do).

So maybe I do not understand how the elasticsearch boolean query works, I don't know. A working example that can achieve the above case will be highly appreciated as well.

For example, the following does not work and yields the result set of 4,5,6 only:

{'query': {'bool': {'should': [{'bool': {'must': [{'range': {'x': {'gte': 4}}}, {'range': {'x': {'lte': 6}}}]}}, {'match': {'x': 2}}]}}}

Solution

  • It looks like you did everything right. Try the following.

    POST _bulk
    {"index":{"_index":"test","_id":"2"}}
    {"x":2}
    {"index":{"_index":"test","_id":"4"}}
    {"x":4}
    {"index":{"_index":"test","_id":"5"}}
    {"x":5}
    {"index":{"_index":"test","_id":"6"}}
    {"x":6}
    {"index":{"_index":"test","_id":"7"}}
    {"x":7}
    {"index":{"_index":"test","_id":"8"}}
    {"x":8}
    {"index":{"_index":"test","_id":"9"}}
    {"x":9}
    {"index":{"_index":"test","_id":"10"}}
    {"x":10}
    {"index":{"_index":"test","_id":"11"}}
    {"x":11}
    {"index":{"_index":"test","_id":"12"}}
    {"x":12}
    

    --

    POST test/_search
    {
      "query": {
        "bool": {
          "should": [
            {
              "bool": {
                "must": [
                  {
                    "range": {
                      "x": { "gte": 4 }
                    }
                  },
                  {
                    "range": {
                      "x": { "lte": 6 }
    
                    }
                  }
                ]
              }
            },
            {
              "match": {"x": 2}
            }
          ]
        }
      }
    }
    

    output: 4,5,6,2 as expected.

    enter image description here