'Elasticsearch query: combine must_not conditions

I am creating a query filter for multiple court documents in elasticsearch. In each document, the source contains a JSON object, defining the court that took the decision. To make the question clear, I will add some examples.

E.g. Court of Appeal in city one:

"_source": {
      "CourtInstance": {
            "CourtInstance": "",
            "CourtInstanceType": "Court of appeal",
            "CourtInstanceDivission": "",
            "CourtInstanceLocation": "cityOne"
        },
        *** further source omitted***
}

E.g. court of appeal in city two:

"_source": {
      "CourtInstance": {
            "CourtInstance": "",
            "CourtInstanceType": "Court of appeal",
            "CourtInstanceDivission": "",
            "CourtInstanceLocation": "cityTwo"
        },
        *** further source omitted***
}

E.g. tribunal in city two, division one (so the local tribunal and the court of appeal nr. 2 share the same city).

"_source": {
      "CourtInstance": {
            "CourtInstance": "",
            "CourtInstanceType": "Tribunal",
            "CourtInstanceDivission": "divissionOne",
            "CourtInstanceLocation": "cityTwo"
        },
        *** further source omitted***
}

Users should be able to filter out a specific court type, e.g. all Courts of appeal, but also just the Court of appeal of cityOne or cityTwo, depending on what is selected by the user.

From what I understand, in order to combine multiple combinations, a bool query needs to be written within the first query (refer: Combining must_not in ElasticSearch Query - Combining two conditions in must_not ElasticSearch - see especially the changes in versions of and the adaption of the query format).

I thus wrote the following query:

{"query": {
    "bool": {
        "must_not" : [
            {
              
                    "bool": {
                        "must": [
                            {
                               "match": {
                                 "CourtInstance.CourtInstanceType": "Court of appeal"
                               }
                            },
                            {
                               "match": {
                                 "CourtInstance.CourtInstanceLocation": "cityOne"
                               }
                            }
                        ]
                    }
                }
            
        ]
    }
}
            
}

This works fine for the Court of Appeal of City one. If the user selects that he/she does not wants to get the results of the court of appeal of city one, the decisions of the court of appeal of city two are still returned.

However, if I change the CourtInstanceLocation to cityTwo, and keep the "CourtInstanceType" at "Court of appeal", the tribunal of cityTwo is also filtered out, even though this one should still be there. The "CourtInstance.CourtInstanceType" of the tribunal !== "Court of appeal" but === "Tribunal"

E.g of query that filters out both the court of appeal of city one and the tribunal of city two:

{"query": {
    "bool": {
        "must_not" : [
            {
              
                    "bool": {
                        "must": [
                            {
                               "match": {
                                 "CourtInstance.CourtInstanceType": "Court of appeal"
                               }
                            },
                            {
                               "match": {
                                 "CourtInstance.CourtInstanceLocation": "cityTwo"
                               }
                            }
                        ]
                    }
                }
            
        ]
    }
}
            
}

EDIT: the mappings of the index

"CourtInstance" : {
          "properties" : {
            "CourtInstance" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            },
            "CourtInstanceLocation" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            },
            "CourtInstanceType" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            }

Does someone have any idea why this is happening? The condition should be that if both conditions are met (AND) the decisions of this specific court won't be shown.

Thank you and kind regards.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source