kcm
kcm

Reputation: 1358

Combining must_not in ElasticSearch Query

I'm currently struggling with an ElastSearch query which currently looks the following:

...
"query": {
    "bool": {
        "must_not": [
            {
                "term": {
                    "bool-facet.criteria1": {
                        "value": false
                    }
                }
            },
            {
                "term": {
                    "bool-facet.criteria2": {
                        "value": false
                    }
                }
            }
        ]
    }
}
...

So now when either criteria1 OR criteria2 matches, the documents are ignored. How must the query look like so that only documents that match criteria1 AND criteria2 are ignored?

Upvotes: 31

Views: 74276

Answers (5)

Sajad Ranjbar
Sajad Ranjbar

Reputation: 1

This is what worked for me:

GET index/_search
{
  "query": {
    "bool": {
      "must_not": [
        {
          "bool": {
            "must": [
              {
                "term": {
                  "bool-facet.criteria1": false
                }
              },
              {
                "term": {
                  "bool-facet.criteria2": false
                }
              }
            ]
          }
        }
      ]
    }
  }
}

Upvotes: 0

Niek
Niek

Reputation: 1619

This behavior worked for me under 6.5.4:

GET model/_search
{
    "query": {
        "bool": {
            "must_not": [
                {
                    "exists": {
                        "field": "field1"
                    }
                },
                {
                    "exists": {
                        "field": "field2"
                    }
                },
                {
                    "exists": {
                        "field": "field3"
                    }
                }
            ]
        }
    }
}

Upvotes: 2

Mnebuerquo
Mnebuerquo

Reputation: 5979

The following arrangement worked for me on a similar query in 5.5.1:

"query": {
    "bool": {
        "must": [
            {
                "bool":{
                    "must_not":{
                        "term":{
                            "bool-facet.criteria1": false
                        }
                    }
                }
            },
            {
                "bool":{
                    "must_not":{
                        "term":{
                            "bool-facet.criteria2": true
                        }
                    }
                }
            }
        ]
    }
} 

The other answers may have been correct for other versions, but did not work for me in 5.5.1.

Upvotes: 17

kcm
kcm

Reputation: 1358

Since updating elasticsearch version was not possible I had to find another solution. This is what worked for me:

"query": {
    "bool": {
        "must_not" : [
            {
                "query": {
                    "bool": {
                        "must": [
                            {
                               "term": {
                                 "bool-facet.criteria1": false
                               }
                            },
                            {
                               "term": {
                                 "bool-facet.criteria2": false
                               }
                            }
                        ]
                    }
                }
            }
        ]
    }
}

Upvotes: 6

pickypg
pickypg

Reputation: 22342

If you want simple AND-behavior, then just nest another bool query inside of it:

"query": {
  "bool": {
    "must_not": [
      {
        "bool": {
          "filter": [
            {
              "term": {
                "bool-facet.criteria1": false
              }
            },
            {
              "term": {
                "bool-facet.criteria2": false
              }
            }
          ]
        }
      }
    ]
  }
}

Note that by using the filter (as it's a yes/no question with no scoring needed, but if you wanted scoring, then you would use must instead of filter) you get the desired AND behavior. This changes the question to "not(any document that has criteria1 == false AND criteria2 == false)".

Upvotes: 37

Related Questions