12
votes

I am trying to create an elasticsearch query that has to match one of three queries on seperate fields and also have an extra query that is not a requirement to be matched. The problem with doing bool queries and the MUST clause is that it has to match all 3, and with the SHOULD it not always matches the ones that are required, except when using minimum_should_match set to 2. In that case, it doesnt match on documents that match one of the 3 required ones because of the minimum match.

My current query is like this (sorry, dont have the code right here)

query - bool - must - query 1 - query 2 - query 3 - should - query 4

I have also tried the following, but it doesnt make the 4th query optional

query - bool - should - query 1 - query 2 - query 3 - query 4 - minimum_should_match: 2

How would one go about and create a query that MUST match one of three queries and optionally rank those with the 4th query higher.

1

1 Answers

36
votes

Nesting bool queries should get you the results you are looking for. We need to match either query one, two or three, while optionally matching query 4.

"query": {
    "bool": {
        "must": [
           {
               "bool": {
                   "should": [
                      {
                          //query1
                      },
                      {
                          //query2
                      },
                      {
                          //query3
                      }
                   ],
                   "minimum_number_should_match": 1
               }
           }
        ],
        "should": [
           {
               //query4
           }
        ]
    }
}

The query must match at least one of the should clauses of queries one through 3, and optionally should match query 4.

Documents that match query 1,2,3 and 4 all at once will rank the highest, as I assumed you did not mean exclusive or.