1
votes

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"
          }
        }
      }
2
can you please share some sample index data, so that it would be easy to reproduce your issue ?ESCoder
@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?Niklas
please go through my comments below, and let me know if your issue is resolved or not 🙂ESCoder

2 Answers

1
votes

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"
          }
        }
      }
    ]
0
votes

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.