1

I just started working with ES I am facing an issue with the query body I need to filter results using two fields, price and discount. It works fine when I use them with must but some of the documents do not contain a discount field. how to get those too. I am confused about how to write the query. below is what I am using currently. It returns the response without discount but does not apply a range filter. Please help me to fix this issue and explain how it works.

"bool": {
      "filter": [
        {
            "bool": {
                "should": [
                   {
                   "range": {
                      "discount": {
                            "gte": $minDiscount,
                            "lte": $maxDiscount
                            }
                        }
                    }
                ],
                "must":[
                    {
                    "range": {
                       "price": {
                            "gte": $minPrice,
                            "lte": $maxPrice
                             }
                          }
                      }
                ]
            }
        },
       ]
     }

1 Answer 1

1

Let me explain it with an example, lets consider that you have following four documents in ES.

PUT your-index/_doc/1
{
    "price" : 5000,  -> This document price and discount will not be in range.
    "discount" : 80
}

{
    "price" : 100,
    "discount" : 10
}

{
    "price" : 200,
    "discount" : 20
}

{
  "price" : 300 --> this document doesn't have discount field
}

Now if you search the documents whose price range is between 10 to 1000, and discount is between 10 to 30, but you also want last document to also come, as it doesn't have discount, but price is under the range.

** Search query for above requirement**

POST your-index/_search
{
    "query": {
        "bool": {
            "should": [
                {
                    "range": {
                        "discount": {
                            "gte": 10,
                            "lte": 30
                        }
                    }
                },
                {
                    "range": {
                        "price": {
                            "gte": 10,
                            "lte": 1000
                        }
                    }
                }
            ]
        }
    }
}

And search result

"hits": [
            {
                "_index": "71671533",
                "_id": "1",
                "_score": 2.0,
                "_source": {
                    "price": 100,
                    "discount": 10
                }
            },
            {
                "_index": "71671533",
                "_id": "2",
                "_score": 2.0,
                "_source": {
                    "price": 200,
                    "discount": 20
                }
            },
            {
                "_index": "71671533",
                "_id": "3",
                "_score": 1.0,
                "_source": {
                    "price": 300
                }
            }
        ]

Things to note:

  1. I used should array for searching the documents with the discount and price range, this way any one condition matching the range will be returned, and as you can notice, fourth document doesn't have the discount field but its matching in the price range, so its coming in search result.
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the reply Amit. but with documents containing both discount and price. The range filter is not working if I search price from 1 to 20, It is also returning me 20+ too.
@GurjitSingh, maybe that b/c its matching another filter, can you keep just one filter and try it.
I just have a filter with ID to match with the right document. Without that, it won't work.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.