1

I'm trying write a query to achieve the following result:

field1: value1 AND 
field2: value2 OR "" (empty)

I've tried the following but it always returns me empty results:

{
  "_source": ["field1", "field2"], 
  "query": {
    "bool": {
      "must": [
        {"match": { "field1": "value1" }},
        {
          "bool": {
            "should": [
              { 
                "match": {
                  "field2": "value2"
                }
              }
            ],
            "must_not": [
              {
                "exists": { "field": "field2" }
              }
            ]
          }
        }
      ]
    }
  }
}

I believe I'm making a query that contradicts itself.

1
  • 1
    I think you made a logical mistake by having must_not and should on the same level. Must_not should be under should[{...},bool:{must_not:[...]}] Commented Feb 13, 2018 at 16:18

1 Answer 1

4

This is looking very complicated.

Try using queryStringQuery Try rewriting your query like this

{
    "_source": ["field1", "field2"], 
    "query": {
      "query_string": {
        "query": "field1:value1 AND (field2:value2 OR (!field2:*))"
      }
    }

}

If you still want to use in this format

You have used must_not clause which would mean somewhat this as below according to your use case.

field1: value1 AND

field2: value2 AND NOT "" (empty)

What you should do is

   {
  "_source": [
    "field1",
    "field2"
  ],
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "field1": "value1"
          }
        },
        {
          "bool": {
            "should": [
              {
                "match": {
                  "field2": "value2"
                }
              },
              {
                "bool": {
                  "must_not": [
                    {
                      "exists": {
                        "field": "field2"
                      }
                    }
                  ]
                }
              }
            ]
          }
        }
      ]
    }
  }
}

But it would be more easy for you to use queryString if you want to analyze the terms in query first which you have done in your query.

So using queryString OR bool in your this case would be same

Sign up to request clarification or add additional context in comments.

5 Comments

Since it's an exact match I wouldn't use query_string. Match or term should be just as good. But in general it's a good solution.
@MrSimple Thanks.But in the question he is using match queries which are also full text queries and will be analysed.That is why i suggested this .
Thank you @MrSimple and Gaurav-Arya. In fact I'm not yet sure which one should I go for, exact match or full-text. I'll try both.
Try to think it according to you use case. Full text queries first analyzes the search string and then searches the tokens generated. Exact match queries search the search string as it is. What you have done in question is a full text query. Here are links reffering to it. full text ->elastic.co/guide/en/elasticsearch/reference/current/… term level ->elastic.co/guide/en/elasticsearch/reference/current/…
wouldn't the exists in this case look to see if the entire field exists.. not just that the field is empty. i have the same issue... and this 'exists' unfortunately doesn't return me the empty string document.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.