У меня большой набор данных для сайта электронной коммерции. Для продавца я хочу показать агрегацию по продажам на единицу товара с гранулярностью 1 день и диапазонами дат агрегации, варьирующимися от 1 дня до 1 года, отсортированными по продажам.
Для каждого элемента существует идентификатор фильтра, связанный с ним. Таким образом, перед вычислением агрегации в запросеasticsearch постепенно применяются следующие фильтры:
merchantId -> filterId -> диапазон дат -> группировка по элементу и сумма -> сортировка
Одним из возможных способов моделирования данных является использование вложенных документов:
{
merchantId: testMerchant,
itemId: testItem,
filterId: testFilter:
perDaySales: [
{
orderDate: 2019-08-01,
sales: 100
},
{
orderDate: 2018-10-01,
sales: 100
}
]
}
Однако проблема в том, что у нас высокая частота обновления (500 обновлений в секунду) для filterId. Поэтому, если мы обновляем filterId для одного элемента ,asticsearch должен переиндексировать 365 документов (поскольку мы храним данные за последние 365 дат, а вложенные поля хранятся в виде отдельных документов). Это кажется излишним. Благодаря такой непрерывной индексации задержка поиска значительно увеличивается. Кроме того, GC включается часто, поскольку давление JVM быстро возрастает из-за индексации огромного количества документов.
В качестве альтернативы, если используются отношения родитель-потомок, агрегация происходит очень медленно. Поскольку это пользовательский интерфейс, я не хочу, чтобы ответы были очень медленными.
Другая возможность - использовать соединение на стороне приложения. Сохранить itemId для сопоставления filterId в другом индексе или другом хранилище данных. Получите все itemIds для заданных filterIds, а затем передайте эти itemIds в запрос Flexiblesearch в качестве фильтра. Тем не менее, один продавец может иметь сотни тысяч товаров. Поэтому передача такого большого списка в запросе ES невозможна. Я не могу передать частичный список элементов для запроса, так как мне нужно показать страницу результатов в порядке убывания продаж по элементу. Таким образом, для сортировки всех элементов в запросе ES требуется список всех элементов заранее.
Существует ли эффективный способ в таких случаях моделировать данные, чтобы скорость индексации не умножалась без ущерба для производительности агрегирования?