gpt4 book ai didi

Mongodb计算所有按条件匹配的对象中的所有数组元素

转载 作者:IT老高 更新时间:2023-10-28 13:24:34 24 4
gpt4 key购买 nike

我有一个这样的对象的事件日志集合:

{
"_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")
}
]
}

如果我进行以下查询:

db.objects.find({
"createddate": {$gte : ISODate("2015-08-30T00:00:00.000Z")},
"activity.action" : "test_action"}
}).count()

它返回包含“test_action”的文档计数(本集中 3 个),但我需要获取所有 test_actions 的计数(本集中 4 个)。我该怎么做?

最佳答案

最“高效”的方法是跳过 $unwind总而言之$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]
]
}
}
}
}}
])

从 MongoDB 3.2 版开始,我们可以使用 $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" ]
}
}
}
}
}
}}
])

使用 $unwind 会导致文档去规范化并有效地为每个数组条目创建一个副本。在可能的情况下,您应该避免这种情况,因为这通常会带来极高的成本。相比之下,过滤和计算每个文档的数组条目要快得多。与许多阶段相比,简单的 $match$group 管道也是如此。

关于Mongodb计算所有按条件匹配的对象中的所有数组元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32305897/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com