Реализация зависимых фильтров в Elasticsearch в один запрос

vafir

Новичок
Привет всем!
У меня есть большой индекс в Elasticsearch с товарами. Товары выводятся в каталоге в зависимости от фильтров выбранных пользователем.
Вот пример товаров в эластике.
Goods
First:
brand: [adidas]
color: [red, green, blue]
size:[39,40,41]
cost:[2000, 3000]​
Second:
brand: [nike]
color: [yellow]
size:[43]
cost:[4000, 4700]​
Third:
brand: [reebok]
color: [blue]
size:[41]
cost:[3000]​

Когда пользователи ничего не выбрали, я делаю такой запрос:
Default query:
{
"query" : {
"query_string" : {
"query" : "*"​
}​
},
"aggs" : {
"colors" : {
"terms" : {"field" : "color"}​
},

"sizes" : {
"terms" : {"field" : "size"}​
},
"brands" : {
"terms" : {"field" : "brand"}​
},
"max_price" : { "max" : { "field" : "price" }},
"min_price" : { "min" : { "field" : "price"}}​
},
"size" : 15​
}​

Get response:
"hits" : {
"total" : 10000,
...
"hits" : [some goods]​
},
"aggregations" : {
"brands" : [nike, adidas, reebok],
"colors" : [red, green, blue, yellow],
"sizes" : [39,40,41,42,43],
"min_price" : 2000,
"max_price" : 4700​
}​

Получаю агрегацию по полям по всему индексу. Агрегация идет на заполение выпадающих фильтров.

Если я выбиру фильтр brand=adidas и сделаю сабмит формы я буду должены выполнить два запроса на сервере: Default query: - получение данных для фильтров и второй Second query

Second query:
"query" : {
"query_string" : {
"query" : "brand:adidas"​
},
"aggs" : {
"colors" : {
"terms" : {"field" : "color"}​
},

"sizes" : {
"terms" : {"field" : "size"}​
},
"max_price" : { "max" : { "field" : "price" }},
"min_price" : { "min" : { "field" : "price"}}​
}
"size" : 15,​
}​

Получаем:
"hits" : {
"total" : 1,
...
"hits" : [fisrt:adidas]​
},
"aggregations" : {
"colors" : [red, green, blue],
"sizes" : [39,40,41],
"min_price" : 2000,
"max_price" : 3000​
}​

Second query - позволит мне заблокировать лишние элементы фильтров (цвета, не удовлетворяющие бренду, размеры и т.д.)

Фильтры:
brand:
adidas[enabled]
nike[enabled]
reebok[enabled]​
size:
39[enabled]
40[enabled]
41[enabled]
42[disabled] becouse adidas has't size 42
43[disabled] becouse adidas has't size 43​
color:
red[enabled]
green[enabled]
blue[enabled]
yellow[disabled] becouse adidas has't color yellow​

Если я выберу barand:adidas + color:green я буду должен выполнить три запроса: Default, Second("query" : "brand:adidas AND color:green"), Third query - для блокировки лишних брендов
"query" : {
"query_string" : {
"query" : "color:green"​
},
"aggs" : {
"brands" : {
"terms" : {"field" : "brand"}​
}​
}​
}​

Кто-нибудь знает как можно объединить эти запросы в один, типо подзапросов в SQL или еще как-нибудь, чтобы за один запрос я получил всю информацию по каталогу и по заблокированным фильтрам

total_goods: 1000
total_brends: [adidas, nike, reebok]
total_colors:[red, green, blue, yellow]
total_sizes: [36-45]
min_price: 2000
max_price: 4700

goods_by_query:26
brands_by_query:[adidas]
colors_by_query:[red, green, blue]
sizes_by_query:[39-41]
min_price_by_query: 3000
max_price_by_query: 4700
goods_by_query:[some goods]
 
Сверху