How to add compound conditions in search template?

Use Case:
We have 2 conditions

  1. Query parameter matches
  2. All of dishFamilyId, dishTypeId, dishPreparationStyleId should match (they might not be present as well) Eg. Its possible that dishTypeId and dishPreparationStyleId is not present at all and only dishFamilyId is present

If either of the 2 conditions are passed, then the document should be a match

Problem:
With the current template we have designed, we need to put all possible combinations of dishFamilyId, dishTypeId, dishPreparationStyleId in order to successfully render the template

{
  "from": 0,
  "size": {{maxResult}}{{^maxResult}}50{{/maxResult}},
  "query": {
    "function_score": {
      "query": {
        "bool": {
          "filter": [
            {
              "bool": {
                "should": [
                  {
                    "match_phrase": {
                      "name.synonym": {
                        "query": "{{query}}",
                        "slop": 0
                      }
                    }
                  }
                  {{#dishFamilyId}}
                    {{#dishTypeId}}
                      {{#dishPreparationStyleId}}
                      ,{
                        "bool": {
                          "must": [
                            {
                              "multi_match": {
                                "query": "{{dishFamilyId}}",
                                "fields": [
                                  "dishFamily.bucket1",
                                  "dishFamily.bucket2",
                                  "dishFamily.bucket3"
                                ],
                                "boost": 1,
                                "operator": "OR"
                              }
                            },
                            {
                              "multi_match": {
                                "query": "{{dishTypeId}}",
                                "fields": [
                                  "dishType.bucket1",
                                  "dishType.bucket2",
                                  "dishType.bucket3"
                                ],
                                "boost": 1,
                                "operator": "OR"
                              }
                            },
                            {
                              "multi_match": {
                                "query": "{{dishPreparationStyleId}}",
                                "fields": [
                                  "dishPreparationStyle.bucket1",
                                  "dishPreparationStyle.bucket2",
                                  "dishPreparationStyle.bucket3"
                                ],
                                "boost": 1,
                                "operator": "OR"
                              }
                            }
                          ]
                        }
                      }
                      {{/dishPreparationStyleId}}
                      {{^dishPreparationStyleId}}
                      ,{
                        "bool": {
                          "must": [
                            {
                              "multi_match": {
                                "query": "{{dishFamilyId}}",
                                "fields": [
                                  "dishFamily.bucket1",
                                  "dishFamily.bucket2",
                                  "dishFamily.bucket3"
                                ],
                                "boost": 1,
                                "operator": "OR"
                              }
                            },
                            {
                              "multi_match": {
                                "query": "{{dishTypeId}}",
                                "fields": [
                                  "dishType.bucket1",
                                  "dishType.bucket2",
                                  "dishType.bucket3"
                                ],
                                "boost": 1,
                                "operator": "OR"
                              }
                            }
                          ]
                        }
                      }
                      {{/dishPreparationStyleId}}
                    {{/dishTypeId}}
                    {{^dishTypeId}}
                        {{#dishPreparationStyleId}}
                        ,{
                          "bool": {
                            "must": [
                              {
                                "multi_match": {
                                  "query": "{{dishFamilyId}}",
                                  "fields": [
                                    "dishFamily.bucket1",
                                    "dishFamily.bucket2",
                                    "dishFamily.bucket3"
                                  ],
                                  "boost": 1,
                                  "operator": "OR"
                                }
                              },
                              {
                                "multi_match": {
                                  "query": "{{dishPreparationStyleId}}",
                                  "fields": [
                                    "dishPreparationStyle.bucket1",
                                    "dishPreparationStyle.bucket2",
                                    "dishPreparationStyle.bucket3"
                                  ],
                                  "boost": 1,
                                  "operator": "OR"
                                }
                              }
                            ]
                          }
                        }
                        {{/dishPreparationStyleId}}
                        {{^dishPreparationStyleId}}
                        ,{
                          "bool": {
                            "must": [
                              {
                                "multi_match": {
                                  "query": "{{dishFamilyId}}",
                                  "fields": [
                                    "dishFamily.bucket1",
                                    "dishFamily.bucket2",
                                    "dishFamily.bucket3"
                                  ],
                                  "boost": 1,
                                  "operator": "OR"
                                }
                              }
                            ]
                          }
                        }
                        {{/dishPreparationStyleId}}
                    {{/dishTypeId}}
                  {{/dishFamilyId}}
                  {{^dishFamilyId}}
                    {{#dishTypeId}}
                      {{#dishPreparationStyleId}}
                      ,{
                        "bool": {
                          "must": [
                            {
                              "multi_match": {
                                  "query": "{{dishTypeId}}",
                                  "fields": [
                                    "dishType.bucket1",
                                    "dishType.bucket2",
                                    "dishType.bucket3"
                                  ],
                                  "boost": 1,
                                  "operator": "OR"
                                }
                            },
                            {
                              "multi_match": {
                                "query": "{{dishPreparationStyleId}}",
                                "fields": [
                                  "dishPreparationStyle.bucket1",
                                  "dishPreparationStyle.bucket2",
                                  "dishPreparationStyle.bucket3"
                                ],
                                "boost": 1,
                                "operator": "OR"
                              }
                            }
                          ]
                        }
                      }
                      {{/dishPreparationStyleId}}
                      {{^dishPreparationStyleId}}
                      ,{
                        "bool": {
                          "must": [
                            {
                              "multi_match": {
                                  "query": "{{dishTypeId}}",
                                  "fields": [
                                    "dishType.bucket1",
                                    "dishType.bucket2",
                                    "dishType.bucket3"
                                  ],
                                  "boost": 1,
                                  "operator": "OR"
                                }
                            }
                          ]
                        }
                      }
                      {{/dishPreparationStyleId}}
                    {{/dishTypeId}}
                    {{^dishTypeId}}
                      {{#dishPreparationStyleId}}
                      ,{
                        "bool": {
                          "must": [
                            {
                              "multi_match": {
                                "query": "{{dishPreparationStyleId}}",
                                "fields": [
                                  "dishPreparationStyle.bucket1",
                                  "dishPreparationStyle.bucket2",
                                  "dishPreparationStyle.bucket3"
                                ],
                                "boost": 1,
                                "operator": "OR"
                              }
                            }
                          ]
                        }
                      }
                      {{/dishPreparationStyleId}}
                    {{/dishTypeId}}
                  {{/dishFamilyId}}
                ],
                "minimum_should_match": 1
              }
            }
          ]
        }
      }
    }
  }
}

Is there any simpler way like adding compound conditions in the search template or maybe a completely different template idea?

There are no parameter for Match query for the behavior on the documents missing the target field. You have to use boolean query for "match if exists" query.

{
  "query":{
    "bool":{
      "should":[
        {
          "bool":{
            "must_not": [
              {"exists": {
                "field": "dishTypeId"
              }}
            ]
          }
        },
        {
          "match":{
            "dishTypeId":{
              "query": "xxx"
            }
          }
        }
      ]
    }
  }
}

Then combine such queries as follows. It could be less complicated than yours. OR is should clause with minimum_should_match:1 and AND is must caluse for boolean queris.

bool(
  (Query parameter matches) OR 
  bool(
    bool((dishFamilyId not exist) OR (dishFamilyId==some)) AND 
    bool((dishTypeId not exist) OR (dishFamilyId==some)) AND
    bool((dishPreparationStyleId not exist) OR (dishFamilyId==some)
  )
)
2 Likes

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.