Multiple range filters for same field

Hey!

We're currently filtering our search with terms and range filters. It seems like filters are combined using AND which is what we need.

{
    body: {
        bool: {
            must: {
                query_string: {
                    query: '...'
                }
            },            
            filter: [
                { terms: { 'foobar': ['foo', 'bar'] } },
                { range: { 'fubaz': { "gte": 100, "lte": 200 } } },
            ]
        }
    }
}

Now we're wondering how we could add two ranges for the same field. For example:

  • foobar is foo or bar
  • AND
  • fubaz is (gte: 10, lte: 20) or (gte: 50, lte: 75)

How would that look? Any links/tips appreciated.

Thanks!

Yep, totally doable! You have to start combining multiple boolean queries to do it. So it'd be something like:

{
    body: {
        bool: {
            must: {
                query_string: {
                    query: '...'
                }
            },            
            filter: [
              { terms: { 'foobar': ['foo', 'bar'] } },
              {
                bool: {
                  should: [
                    { range: { 'fubaz': { "gte": 10, "lte": 20 } } },
                    { range: { 'fubaz': { "gte": 50, "lte": 75 } } },
                  ]
                }
              }
            ]
        }
    }
}

Everything in a filter is required, so that takes care of the AND between the terms and the ranges. A terms filter is naturally an OR, so that handles that. And for the ranges, we setup a boolean with a should containing each range, which satisfy the OR there.

It gets a bit complicated with deep boolean logic due to the nesting, but not too terrible once you get used to it :slight_smile: You can keep embedding these boolean queries as much as you want/need to express the appropriate boolean logic.

5 Likes

Awesome, that did the trick. Thanks a lot, Zachary!

Great! Happy to help :slight_smile:

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