У меня есть коллекция в MongoDB с образцом документа следующим образом:
{
"_id" : ObjectId("58114e5e43d6420b7db4e15c"),
"browser" : "Chrome",
"name": "hyades",
"country" : "in",
"day" : "16-10-21",
"ip" : "0.0.0.0",
"class" : "A123"
}
Постановка задачи
Я должен иметь возможность группировать по любому из полей при получении определенного количества IP-адресов.
Запрос агрегации -
[
{$group: {_id: '$class', ip_arr: {$addToSet: '$ip'}}},
{$project: {class: '$_id.class', ip: {$size: '$ip_arr'}}}
]
дает желаемые результаты, но медленно. Точно так же подсчет ip
с использованием другого $group
происходит медленно. Выход -
[{class: "A123",ip: 42},{class: "B123", ip: 56}..]
Что я пробовал
Я рассматривал возможность использования Hyperloglog для этого. Я попытался использовать реализацию Redis. Я пытаюсь передать все данные, проецируя только то, что я группирую, и PFADD
в соответствующую структуру Hyperloglog в Redis.
Логика выглядит так -
var stream = Model.find({}, {ip: 1, class: 1}).stream();
stream.on('data', function (doc) {
var hash = "HLL/" + doc.class;
client.pfadd(hash, doc.ip);
});
Я пытался запустить это для миллиона с лишним точек данных. Размер передаваемых данных составлял около 1 ГБ при скорости соединения 1 Гбит/с между Mongo и сервером Node. Я ожидал, что этот код будет работать достаточно быстро. Однако это было довольно медленно (медленнее, чем подсчет в MongoDB).
Еще одна вещь, о которой я подумал, но не реализовал, заключалась в том, чтобы предварительно создавать сегменты для каждого класса и увеличивать их в реальном времени по мере поступления данных. Но память, необходимая для поддержки любой произвольной группировки, была огромной, поэтому от этой идеи пришлось отказаться.
Пожалуйста, предложите, что я могу делать неправильно или что я мог бы улучшить здесь, чтобы я мог в полной мере использовать гиперлоглог (я не ограничен Redis и открыт для любой реализации)
PFADD
каждый раз, когда вы вставляете элемент в MongoDB. Текущее решение не будет быстрее, так как вам все равно придется читать данные из MongoDB. - person for_stack   schedule 18.11.2016