1

I've got two different queries against my elasticsearch. The difference between these two queries is that the first one got the two search criteria in one boolean should query and he second splits it into two single bool should queries. The first one return the expected response but the second one doesnt match to any document even if there are documents which contains both criteria. If i refactor the second one so that the two splitted bool should queries are encapsulatec by a bool should querie it returns the expected response like it is for querie 1.

The question is why does query 2 doesn't return the response as 1 and 3 do? Am i missing something?

EDIT: provided example data

EDIT: my problem solved, it was just a spelling mistake while building the range query in my code and i doesnt recognize it -.- but maybe the explanation from the answer here will help somebody else.

1.

GET _search
{
  "query": {
    "bool": {
      "filter": [
        {
          "bool": {
            "should": [
              {
                "range": {
                  "streetNr": {
                    "from": "1",
                    "to": "100",
                    "include_lower": true,
                    "include_upper": true,
                    "boost": 1
                  }
                }
              },
              {
                "match": {
                  "geographicAddress.city": {
                    "query": "Berlin"
                  }
                }
              }
            ],
            "minimum_should_match": "1"
          }
        }
      ]
    }
  }
}
GET _search
{
  "query": {
    "bool": {
      "filter": [
        {
          "bool": {
            "should": [
              {
                "range": {
                  "streetNr": {
                    "from": "1",
                    "to": "100",
                    "include_lower": true,
                    "include_upper": true,
                    "boost": 1
                  }
                }
              }
            ],
            "minimum_should_match": "1"
          }
        },
        {
          "bool": {
            "should": [
              {
                "match": {
                  "geographicAddress.city": {
                    "query": "Berlin"
                  }
                }
              }
            ],
            "minimum_should_match": "1"
          }
        }
      ]
    }
  }
}
GET _search
{
  "query": {
    "bool": {
      "filter": [
        {
          "bool": {
            "should": [
              {
                "bool": {
                  "should": [
                    {
                      "range": {
                        "streetNr": {
                          "from": "1",
                          "to": "100",
                          "include_lower": true,
                          "include_upper": true,
                          "boost": 1
                        }
                      }
                    }
                  ],
                  "minimum_should_match": "1"
                }
              },
              {
                "bool": {
                  "should": [
                    {
                      "match": {
                        "geographicAddress.city": {
                          "query": "Berlin"
                        }
                      }
                    }
                  ],
                  "minimum_should_match": "1"
                }
              }
            ],
            "minimum_should_match": "1"
          }
        }
      ]
    }
  }
}

Example data:

      {
        "_index": "stof_64371064",
        "_type": "_doc",
        "_id": "1",
        "_score": 0.0,
        "_source": {
          "streetNr": 90,
          "geographicAddress": {
            "city": "Berlin"
          }
        }
      },
      {
        "_index": "stof_64371064",
        "_type": "_doc",
        "_id": "2",
        "_score": 0.0,
        "_source": {
          "streetNr": 10,
          "geographicAddress": {
            "city": "Berlin"
          }
        }
      }
3
  • can you please share some sample index data, so that it would be easy to reproduce your issue ? Commented Oct 15, 2020 at 15:19
  • @Bhavya sorry for my late reply, I only just got around to reading it. In your answer you rebuil my second query in a manner that is kinda is like my third query. (except for the bool filter) The example data you provide for your explanation is quite well for my case, but i still dont get why my form of the second question doesnt return that document. You said it is like a must clause so that both documents in your example should match, doesn't it? Commented Oct 16, 2020 at 12:12
  • please go through my comments below, and let me know if your issue is resolved or not 🙂 Commented Oct 16, 2020 at 16:06

2 Answers 2

1

Please refer ES official documentation on bool query, to get a detailed understanding of various clauses.

The structure of your first search query is like -

 {
  "query": {
    "bool": {
      "filter": [
        {
          "bool": {
            "should": [
              {},
              {}
            ],
            "minimum_should_match": 1
          }
        }
      ]
    }
  }
}

filter clause is wrapping should query, but at the end of should clause, "minimum_should_match": 1 is added which indicates that 1 should clause must be mandatory.

The structure of your second search query is like -

{
  "query": {
    "bool": {
      "filter": [
        {
          "bool": {
            "should": {},
            "minimum_should_match": "1"
          }
        },
        {
          "bool": {
            "should": {},
            "minimum_should_match": "1"
          }
        }
      ]
    }
  }
}

Here since you have added "minimum_should_match": "1" after every should clause, then in a way, it acts like a must clause only, as there is only one condition that needs to be matched in the should clause. filter clause is applied enclosing both the bool should clause, so when both the should clause match, then only you will get the result.

The structure of your third search query is like -

{
  "query": {
    "bool": {
      "filter": [
        {
          "bool": {
            "should": [
              {
                "bool": {
                  "should": [
                    {}
                  ],
                  "minimum_should_match": 1
                }
              },
               {
                "bool": {
                  "should": [
                    {}
                  ],
                  "minimum_should_match": 1
                }
              }
            ],
            "minimum_should_match": 1
          }
        }
      ]
    }
  }
}

In this, you have used multiple combinations of the bool should clause. The first outer bool should clause, wraps two more bool should clause. But here at the end of the outer should clause you have added "minimum_should_match": 1. So though here filter clause is there but it will return a result even if one bool should clause satisfy the condition.

Adding a working example with index data, search query, and search result

Index Data:

{
  "streetNr":0,
  "geographicAddress":{
    "city":"Berlin"
  }
}
{
  "streetNr":90,
  "geographicAddress":{
    "city":"Berlin"
  }
}

Search Query: (Second search query acc to your question)

    {
  "query": {
    "bool": {
      "should": [          <-- note this
        {
          "bool": {
            "should": [
              {
                "range": {
                  "streetNr": {
                    "from": "1",
                    "to": "100",
                    "include_lower": true,
                    "include_upper": true,
                    "boost": 1
                  }
                }
              }
            ],
            "minimum_should_match": "1"
          }
        },
        {
          "bool": {
            "should": [
              {
                "match": {
                  "geographicAddress.city": {
                    "query": "Berlin"
                  }
                }
              }
            ],
            "minimum_should_match": "1"
          }
        }
      ]
    }
  }
}

Search Result:

"hits": [
      {
        "_index": "stof_64371064",
        "_type": "_doc",
        "_id": "1",
        "_score": 0.0,
        "_source": {
          "streetNr": 90,
          "geographicAddress": {
            "city": "Berlin"
          }
        }
      },
      {
        "_index": "stof_64371064",
        "_type": "_doc",
        "_id": "2",
        "_score": 0.0,
        "_source": {
          "streetNr": 0,
          "geographicAddress": {
            "city": "Berlin"
          }
        }
      }
    ]
Sign up to request clarification or add additional context in comments.

7 Comments

@Niklas if you index the same sample data that I gave in my answer, and try out your search query (which you gave in your question), then you will see that it returns the only document with id: 1. This is because, you have added the filter clause, which is wrapping both the bool should clause. And in each bool should clause you have added the minimum_should_match: 1 parameter. That means the document must satisfy both the conditions (given in each bool should clause), then only it will return the required document.
@Niklas second document(according to my answer), will not return with your search query, because the condition of the range is not satisfied. Whereas if you run your first and third search query, then you will find that it returns both the document. This is because in both of them in some way or the other the condition of the should clause is not compulsory.
@Niklas And if you carefully observe, then you will see that your third search query, is quite different from my second search query. As in your third search query you have 4 bool should clause, whereas in my there are only 3 bool should clause
in my third query are only 3 should clauses or did u mean the filter act as kind of a should right there? but nethertheless it doesnt matter for my question. i didnt see that in your hit results the second result got streetNr 0 and so it doesnt match, but in my case it got for example 10 so it should match both and doesnt get returned. You know what i mean? i edited my question with sample data like you did with your hit example to clarify it.
thanks for your effort and the detailed explanation, maybe some others guys find this helpful. In my case i just found out, that it was a spelling mistake in my "geographicAddress" keyword in the case where i build the range query. The query behaves like expected.
|
0

In the should with minimum should match=1 you say that if one of the criteria is right return the document as you have set in query 1 and 3 . But in the second query you have set two criteria inside filter and elasticsearch search and returns those documents which both criterias are valid on them. Because of that your second query behaves such as a must in comparison with should in your other queries.

1 Comment

i dont know if i get you right, but even when the query 2 behaves like a must it should return the documents because there are documents where both matches? Btw. i edtited the query 3 because i was missing one minimum should match=1 in the outside should quey

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.