我在mongodb中有一个非常大的项目集合,其模式无法更改。简化版的样子是这样的:
{event: { address: {ip: "1.1.1.1", port: 80}}}
{event: { address: {ip: "1.1.1.2", port: 80}}}
{event: { address: [{ip: "1.1.1.1", port: 80}, {ip: "1.1.1.1", port: 443}]}}
{event: { address: [{ip: "1.1.1.1", port: 8080}, {ip: "1.1.1.2", port: 443}]}}
[ { "ip" : "1.1.1.1", "count" : 3 },
{ "ip" : "1.1.1.2", "count" : 2 } ]
db.collection.aggregate({$project: {ip: "$event.address.ip"}}, {$group: {_id: "$ip", count: {$sum: 1}}}, {$sort: {count: -1}}, {$limit: 5})
{
"result" : [
{ "_id" : ["1.1.1.1", "1.1.1.2"], "count" : 1 },
{ "_id" : ["1.1.1.1", "1.1.1.1"], "count" : 1 },
{ "_id" : "1.1.1.2", "count" : 1 },
{ "_id" : "1.1.1.1", "count" : 1 } ],
"ok" : 1
}
集合非常大,我无法首先提取应用程序中的所有ip地址,然后计算每个ip地址的事件。
这能用地图/缩小吗。你有什么建议?
虽然这可以通过MapReduce完成,但聚合框架将更快。您需要在计划中添加两个步骤-1)您需要“规范化”格式,使address始终是一个数组,2)然后您需要$unwind该数组,group by_id,ip以消除重复项,然后group by ip以获得您需要的计数。
规格化数组和非数组是很棘手的,但是可以在$unwind
之前和之后使用两个投影来完成。
var p1 = { "$project" : {
"array" : {
"$cond" : [
{
"$eq" : [
"$address.0",
[ ]
]
},
"$address",
[
null
]
]
},
"notarray" : {
"$cond" : [
{
"$ne" : [
"$address.0",
[ ]
]
},
"$address",
[
null
]
]
},
"isArray" : {
"$eq" : [
"$address.0.ip",
[ ]
]
}
}
};
var u = { "$unwind" : "$array" };
var p2 = { "$project" : {
"address" : {
"$cond" : [
"$isArray",
"$array",
"$notarray"
]
}
}
};
相比之下,两个$group
阶段很简单:
var g1 = { "$group" : { "_id" : { "_id" : "$_id", "ip" : "$address.ip" } } };
var g2 = { "$group" : { "_id" : "$_id.ip", "count" : { "$sum" : 1 } } };
下面是我的示例数据:
> db.coll.find()
{ "_id" : ObjectId("52cd0badba17f3b7ed212575"), "address" : { "ip" : "1.1.1.1" } }
{ "_id" : ObjectId("52cd0bc4ba17f3b7ed212576"), "address" : [ { "ip" : "1.1.1.1" }, { "ip" : "1.1.1.1" } ] }
{ "_id" : ObjectId("52cd0bc9ba17f3b7ed212577"), "address" : [ { "ip" : "1.1.1.1" }, { "ip" : "1.1.1.2" } ] }
下面是聚合及其输出:
> db.coll.aggregate(p1, u, p2, g1, g2)
{ "_id" : "1.1.1.1", "count" : 3 }
{ "_id" : "1.1.1.2", "count" : 1 }
问题内容: 我有一个非常庞大的查询,其最简单的形式如下所示: 我需要再添加一个条件,该条件可以让我获得每个代表的应用程序日期不为空的用户数(例如:rep 1具有3个用户的应用程序日期已填写),并将其分配给类别(由于3个用户,rep是某个状态类别)。看起来像这样: 但是,如果我只是将其添加到select语句中,则所有代表将变为status1,因为sum()是在所有使用申请日期的顾问程序上完成的: 您
我想通过聚合pyspark数据帧来分组,同时基于此数据帧的另一列删除重复项(保留最后一个值)。 总之,我想将dropDuplicates应用于GroupeData对象。所以,对于每个组,我只能动态地保留一行。 对于下面的数据帧,直接的组聚合是: 导致以下数据帧: 我希望聚合只使用每个的最新状态。在这种情况下,已在更新为,因此当时,所有基本时间戳大于的聚合应仅对列功能使用此状态。预期的聚合数据帧是:
我正在尝试设置一个搜索查询,该查询应通过多级嵌套字段复合聚合集合,并从该集合中提供一些子聚合指标。我能够按预期使用其存储桶获取复合聚合,但所有存储桶的子聚合指标都带有。我不确定我是否未能正确指出子聚合应考虑哪些字段,或者它是否应放置在查询的不同部分中。 我的收藏看起来类似于以下内容: 贝娄,你可以找到我已经尝试了。尽管所有文档都有一个设置的点击值,但所有存储桶都带有点击总数。 到目前为止,我的回应
我使用复合和术语聚合来获得基于给定字段的分组结果。我还使用基数聚合来获取聚合桶的总计数。 下面是我发送的请求查询,以获得相应的响应: 请求: 答复: 我使用Kibana检查查询,它对我来说很好。 但是,我不确定如何在我的NEST对象语法中使用这个基数聚合器。 这是我的代码: 我将非常感谢任何帮助。
任何人都可以给出代码示例来显示聚合和组合之间的区别。我已经阅读了这篇文章,但不明白它们在代码上有何不同。 请通过代码显示差异。
我有一个数据帧的值,如: 我想得到每个人不同行动的数量。这一点我可以通过