9

The following documents should be found:

matches query 'my text' AND (has not field OR field with value)

I have tried the following:

GET /myIndex/_search

{
  "query": {
    "bool": {
      "must": [
        {
          "query_string": {
            "query": "my text"
          }
        },
        {
        }
      ],
      "filter": {
        "bool": {
          "must_not": {
            "exists": {
              "field": "myField"
            }
          },
          "must": {
            "terms": {
              "myField": [
                "myValue"
              ]
            }
          }
        }
      }
    }
  }
}

It should (but does not) work liek that:

  1. bool combine via OR must and filter parts
  2. first must select by query
  3. filter uses bool which combines by OR must andmust_not`

But this behaves like must combined with must_not via AND clause. E.g. when I removed "must" or "must_not" query works.

How change query to combine "must" with "must_not" via OR clause?

Elasticsearch version is 5.3.2

Cherry
  • 31,309
  • 66
  • 224
  • 364
  • Man, I tried to follow your `AND` `OR` rules but could't. Maybe [this](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html) could help you reorder the clauses. – Eli Oct 26 '17 at 12:16

2 Answers2

7

You need an extra bool filter between the must and must_not terms.

You should also think about your myField field. If it is defined as text or as keyword. Tested with elasticsearch 5.6.1 the following query works:

{
  "query": {
     "bool": {
        "must": [{

          "query_string": {
             "query": "this is a text content"
          }
        }],

        "filter": {
           "bool": {
              "should" : [{                
                 "bool" : {
                    "must_not": {
                      "exists": {
                         "field": "myField"
                       }
                     }
                  }
              },
              {
                "bool" : {
                  "must": {
                    "terms": {
                       "myField.keyword": ["my field exists and has a value"]
                     }
                   }
                }
              }]

         }
      }
   }
  }
}
Eirini Graonidou
  • 1,506
  • 16
  • 24
5

On Elasticsearch 7.X, you can simply do:

{
  "query": {
    "bool": {
      "must": [
        {"match": {"field1": {"query": "Hero"}}}
      ],
      "must_not": [
        {"terms":{"field3":["Batman"]}},
      ]
    }
  }
}
Thomas Ducrot
  • 2,841
  • 1
  • 16
  • 14