我在 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 的限制,并且可以接受任何实现)