У нас есть ~ 20 миллионов документов (предложения отелей), хранящихся в эластичном (1.6.2), и цель состоит в том, чтобы сгруппировать документы по нескольким полям (duration, start_date, adults, kids
) и выбрать одно самое дешевое предложение из каждой группы. Мы должны отсортировать эти результаты по полю стоимости.
Чтобы избежать субагрегации, мы объединили значения целевых полей в одно под названием default_group_field
, соединив их точкой (.
).
Отображение поля выглядит так:
"default_group_field": {
"index": "not_analyzed",
"fielddata": {
"loading": "eager_global_ordinals"
},
"type": "string"
}
Выполняемый нами запрос выглядит так:
{
"size": 0,
"aggs": {
"offers": {
"terms": {
"field": "default_group_field",
"size": 5,
"order": {
"min_sort_value": "asc"
}
},
"aggs": {
"min_sort_value": {
"min": {
"field": "cost"
}
},
"cheapest": {
"top_hits": {
"_source": {}
},
"sort": {
"cost": "asc"
},
"size": 1
}
}
}
}
},
"query": {
"filtered": {
"filter": {
"and": [
...
]
}
}
}
}
Проблема в том, что такой запрос загружается за секунды (2-5сек).
Однако, как только мы выполним запрос без агрегации, мы получим умеренное количество результатов (скажем, "total": 490
) менее чем за 100 мс.
{
"took": 53,
"timed_out": false,
"_shards": {
"total": 6,
"successful": 6,
"failed": 0
},
"hits": {
"total": 490,
"max_score": 1,
"hits": [...
Но с агрегацией это занимает 2 секунды:
{
"took": 2158,
"timed_out": false,
"_shards": {
"total": 6,
"successful": 6,
"failed": 0
},
"hits": {
"total": 490,
"max_score": 0,
"hits": [
]
},...
Кажется, что обработка этого умеренного количества отфильтрованных документов и выбор самого дешевого из каждой группы не должны занимать так много времени. Это можно сделать внутри приложения, что мне кажется уродливым хаком.
Журнал заполнен строками, в которых говорится:
[DEBUG][index.fielddata.plain ] [Karen Page] [offers] Global-ordinals[default_group_field][2564761] took 2453 ms
Вот почему мы обновили наше сопоставление, чтобы выполнить быструю перестройку global_ordinals при обновлении индекса, однако это не оказало заметного влияния на время выполнения запросов.
Есть ли способ ускорить такую агрегацию или, может быть, способ указать эластичности выполнять агрегацию только для отфильтрованных документов.
А может есть другой источник столь долгого выполнения запроса? Любые идеи высоко ценятся!
top_hits
и повторить попытку? (просто чтобы посмотреть, самый тяжелый он или нет, как я предполагаю) - person Andrei Stefan   schedule 06.06.2016top_hits
- это не проблема, на самом деле ее можно устранить. Но это было оставлено для полноты картины. - person prikha   schedule 08.06.2016