aok*_*lov 6 mongodb mongodb-query aggregation-framework
我有一个集合,它是对象的活动日志,如下所示:
{
"_id" : ObjectId("55e3fd1d7cb5ac9a458b4567"),
"object_id" : "1",
"activity" : [
{
"action" : "test_action",
"time" : ISODate("2015-08-31T00:00:00.000Z")
},
{
"action" : "test_action",
"time" : ISODate("2015-08-31T00:00:22.000Z")
}
]
}
{
"_id" : ObjectId("55e3fd127cb5ac77478b4567"),
"object_id" : "2",
"activity" : [
{
"action" : "test_action",
"time" : ISODate("2015-08-31T00:00:00.000Z")
}
]
}
{
"_id" : ObjectId("55e3fd0f7cb5ac9f458b4567"),
"object_id" : "1",
"activity" : [
{
"action" : "test_action",
"time" : ISODate("2015-08-30T00:00:00.000Z")
}
]
}
Run Code Online (Sandbox Code Playgroud)
如果我跟随查询:
db.objects.find({
"createddate": {$gte : ISODate("2015-08-30T00:00:00.000Z")},
"activity.action" : "test_action"}
}).count()
Run Code Online (Sandbox Code Playgroud)
它返回包含"test_action"的文档计数(此集合中为3),但我需要计算所有test_actions(此集合中为4).我怎么做?
最" $unwind高效"的方法是跳过altogther并简单$group地计算.基本上"过滤"数组得到$size的结果$sum:
db.objects.aggregate([
{ "$match": {
"createddate": {
"$gte": ISODate("2015-08-30T00:00:00.000Z")
},
"activity.action": "test_action"
}},
{ "$group": {
"_id": null,
"count": {
"$sum": {
"$size": {
"$setDifference": [
{ "$map": {
"input": "$activity",
"as": "el",
"in": {
"$cond": [
{ "$eq": [ "$$el.action", "test_action" ] },
"$$el",
false
]
}
}},
[false]
]
}
}
}
}}
])
Run Code Online (Sandbox Code Playgroud)
MongoDB的未来版本将会$filter更加简单:
db.objects.aggregate([
{ "$match": {
"createddate": {
"$gte": ISODate("2015-08-30T00:00:00.000Z")
},
"activity.action": "test_action"
}},
{ "$group": {
"_id": null,
"count": {
"$sum": {
"$size": {
"$filter": {
"input": "$activity",
"as": "el",
"cond": {
"$eq": [ "$$el.action", "test_action" ]
}
}
}
}
}
}}
])
Run Code Online (Sandbox Code Playgroud)
使用$unwind会导致文档反规范化并有效地为每个数组条目创建一个副本.在可能的情况下,你应该避免这种情 相比之下,每个文档的过滤和计数数组条目要快得多.由于是一个简单$match和$group管道相比,许多阶段.
您可以使用聚合来执行此操作:
db.objects.aggregate([
{$match: {"createddate": {$gte : ISODate("2015-08-30T00:00:00.000Z")}, {"activity.action" : "test_action"}}},
{$unwind: "$activity"},
{$match: {"activity.action" : "test_action"}}},
{$group: {_id: null, count: {$sum: 1}}}
])
Run Code Online (Sandbox Code Playgroud)
这将产生如下结果:
{
count: 4
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9509 次 |
| 最近记录: |