我在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
将它放入redis中相应的hyperloglog结构中。
逻辑看起来像 -
var stream = Model.find({}, {ip: 1, class: 1}).stream();
stream.on('data', function (doc) {
var hash = "HLL/" + doc.class;
client.pfadd(hash, doc.ip);
});
我试图运行这个数百万个数据点。要流式传输的数据大小约为1GB,Mongo和Node服务器之间的连接速度为1 Gbps。我曾预料到这段代码运行得足够快。但是,它非常慢(比MongoDB中的计数慢)。
我认为但没有实现的另一件事是为每个类预先创建存储桶,并在数据流入的情况下实时增加它们。但是支持任意分组所需的内存是巨大的,所以不得不放弃这个想法
请建议我可能做错了什么,或者我可以在这里做些什么,以便我能够充分利用hyperloglog(我不受Redis约束,并且可以接受任何实现)
答案 0 :(得分:0)
免责声明:我只使用过来自C ++和Linux的redis。 Python,所以这可能没有帮助,但是......
PFADD支持多个参数;在我使用redis HLL计算唯一条目的系统中,我发现对它们进行批处理并一次发送一个包含许多(大约100个)项目的PFADD会导致显着的加速 - 可能是因为避免了redis客户端往返。