elasticsearch bool query combine must with OR elasticsearch bool query combine must with OR elasticsearch elasticsearch

elasticsearch bool query combine must with OR


  • OR is spelled should
  • AND is spelled must
  • NOR is spelled should_not

Example:

You want to see all the items that are (round AND (red OR blue)):

{    "query": {        "bool": {            "must": [                {                    "term": {"shape": "round"}                },                {                    "bool": {                        "should": [                            {"term": {"color": "red"}},                            {"term": {"color": "blue"}}                        ]                    }                }            ]        }    }}

You can also do more complex versions of OR, for example if you want to match at least 3 out of 5, you can specify 5 options under "should" and set a "minimum_should" of 3.

Thanks to Glen Thompson and Sebastialonso for finding where my nesting wasn't quite right before.

Thanks also to Fatmajk for pointing out that "term" becomes "match" in ElasticSearch 6.


I finally managed to create a query that does exactly what i wanted to have:

A filtered nested boolean query.I am not sure why this is not documented. Maybe someone here can tell me?

Here is the query:

GET /test/object/_search{  "from": 0,  "size": 20,  "sort": {    "_score": "desc"  },  "query": {    "filtered": {      "filter": {        "bool": {          "must": [            {              "term": {                "state": 1              }            }          ]        }      },      "query": {        "bool": {          "should": [            {              "bool": {                "must": [                  {                    "match": {                      "name": "foo"                    }                  },                  {                    "match": {                      "name": "bar"                    }                  }                ],                "should": [                  {                    "match": {                      "has_image": {                        "query": 1,                        "boost": 100                      }                    }                  }                ]              }            },            {              "bool": {                "must": [                  {                    "match": {                      "info": "foo"                    }                  },                  {                    "match": {                      "info": "bar"                    }                  }                ],                "should": [                  {                    "match": {                      "has_image": {                        "query": 1,                        "boost": 100                      }                    }                  }                ]              }            }          ],          "minimum_should_match": 1        }      }        }  }}

In pseudo-SQL:

SELECT * FROM /test/objectWHERE     ((name=foo AND name=bar) OR (info=foo AND info=bar))AND state=1

Please keep in mind that it depends on your document field analysis and mappings how name=foo is internally handled. This can vary from a fuzzy to strict behavior.

"minimum_should_match": 1 says, that at least one of the should statements must be true.

This statements means that whenever there is a document in the resultset that contains has_image:1 it is boosted by factor 100. This changes result ordering.

"should": [  {    "match": {      "has_image": {        "query": 1,        "boost": 100      }    }   } ]

Have fun guys :)


This is how you can nest multiple bool queries in one outer bool querythis using Kibana,

  • bool indicates we are using boolean
  • must is for AND
  • should is for OR
GET my_inedx/my_type/_search{  "query" : {     "bool": {             //bool indicates we are using boolean operator          "must" : [       //must is for **AND**               {                 "match" : {                       "description" : "some text"                     }               },               {                  "match" :{                        "type" : "some Type"                   }               },               {                  "bool" : {          //here its a nested boolean query                        "should" : [  //should is for **OR**                               {                                 "match" : {                                     //ur query                                }                               },                               {                                   "match" : {}                                }                                  ]                        }               }           ]      }  }}

This is how you can nest a query in ES


There are more types in "bool" like,

  1. Filter
  2. must_not