Home > Software design >  Elasticsearch query to filter document by specific field value with conditions
Elasticsearch query to filter document by specific field value with conditions

Time:04-13

I want to filter brand names if supplied but return all brands if the filter is empty. here is my query.

"query": {
    "bool": {
        "must": [
            {
                "terms": {
                    "seller": [
                        "Seller1",
                        "Seller2"
                    ]
                }
            },
            {
                "bool": {
                    "should": [
                        {
                            "terms": {
                                "brand": [
                                    "brand1"
                                ]
                            }
                        },
                        {
                            "bool": {
                                "must_not": [
                                    {
                                        "term": {
                                            "brand": {
                                                "value": ""
                                            }
                                        }
                                    }
                                ]
                            }
                        }
                    ]
                }
            },
            {
                "nested": {
                    "path": "Stock",
                    "query": {
                        "bool": {
                            "must": {
                                "match": {
                                    "region": "Regional"
                                }
                            },
                            "filter": [
                                {
                                    "term": {
                                        "pincode": "12345"
                                    }
                                }
                            ]
                        }
                    }
                }
            }
        ]
    }
}

I want if (brand == ["brand1","brand2"]) return those brand products only. But if supplied empty return all. I tried to use it with should, still getting everything if brand is supplied.

CodePudding user response:

There are multipul ways and some of are mentioned below:

Option 1:

You can handle this logic of include, exclude at the application level while creating queries. If you are using Java or python client then it is easily achievable. If you are calling direct search API of elasticsearch then you can not add brand term clause while calling api.

Option 2:

You can use the search template functionality of Elasticsearch.

First you need to create search template as shown in below example:

PUT _scripts/my-search-template
{
  "script": {
    "lang": "mustache",
    "source": """{
     "query": {
    "bool": {
      "must": [
        {
          "terms": {
            "seller": [
              "seller1",
              "seller2"
            ]
          }
        }
      ],
      "filter": [
          {{#filter}}
          {
            "terms": {
              "{{name}}": 
                {{#toJson}}value{{/toJson}}
            }
          }{{/filter}}
      ]
    }
  }
    }"""
  }
}

You can use below API to search using search template, here if you dont pass brand in filter it will not add in actual query:

POST querycheck/_search/template
{
  "id": "my-search-template",
  "params": {
    "filter": [
      {
        "name": "brand",
        "value": [
          "brand1",
          "brand2"
        ]
      }
    ]
  }
}

You can use render api as well to check if query template is generating query correct or not.

POST _render/template
{
  "id": "my-search-template",
  "params": {
    "filter": [
      {
        "name": "brand",
        "value": [
          "brand1",
          "brand2"
        ]
      }
    ]
  }
}
  • Related