How to dynamically bucket low, medium, high on prices and pick 2 per bucker

I have docs containing a price field indexed as such:

{ price: 100 }
{ price: 200 }
{ price: 300 }

The prices can be anything from 100 to 1000.

Depending on a given filter, I want to bucket in low, med, high price points and pick 2 from each category for that search.

Is this possible?

you could play around with a range aggregation, inside of that a terms aggregation on the category field with a size of 2 and inside of that a top_hits aggregation.

Another option is always to execute more than one search, but try the above first.

In the range aggregation is there a way to dynamically calculate the to and from?

Basically if the filtered dataset has max price 400 and min price 100 then the range should be - low: 100 to 200 medium: 200 to 300, high: 300 to 400

you need to define the ranges yourself.

Another approach could be to get the max and min values first and then calculate a proper histogram window out of that.

But that would be two queries right?

yes, that would be two queries