这是我的问题:在我的Mongo数据库中,我有一个包含以下项目的集合:
{
'id': 1,
'steps': [
{
action: 'start',
info: 'foo'
},
{
action: 'stop',
info: 'bar'
}
]
}
我想获得步骤的总数'开始'。
我尝试使用MongoDB聚合框架:我使用$unwind
上的steps.action
和$match
上的steps.action
来匹配“开始”#。
但是,我收到太多数据并达到了聚合的限制:
exception: aggregation result exceeds maximum document size (16MB)
。我不需要数据,我只是想要数,但我无法找到如何做到这一点(尝试使用$ group但没有成功)。
提前致谢,
答案 0 :(得分:10)
如果你想要计数,你可以使用这个
db.test.count({"steps.action":"start"})
但如果步骤包含多个带有操作start
的步骤,则不会考虑这一点。
当您还需要使用start
计算所有步骤时,您需要展开数组,在steps.action上进行匹配,然后将结果分组以进行计数。
db.test.aggregate({$unwind:"$steps"}, {$match:{"steps.action":"start"}},{ $group: { _id: null, count: { $sum: 1 } } })
答案 1 :(得分:4)
试试这个
db.collection.aggregate(
{ $unwind : "$steps" },
{$match:{'steps.action':'start'}},
{$group:{_id:null,count:{$sum:1}}}
).pretty()
答案 2 :(得分:0)
在mongodb聚合框架中,管道阶段最大限制为100MB大小,而它提供的结果是BSON文件或集合文档,最大大小为16MB
所以你可以$match
只需要条件和$group
它,这样只输出小于16MB的所需结果。
答案 3 :(得分:-3)
您可能不需要对此简单查询进行聚合。见下面的代码。
for (var i = 10000; i >= 0; i--) {
var a = {
'id': 1,
'steps': [
{
action: 'start',
info: 'foo'
},
{
action: 'stop',
info: 'bar'
}
]
}
a.id = i;
var rnd = Math.floor((Math.random() * 3) + 1);
if (rnd == 1)
{
a.steps[0].action = 'none';
}
if (rnd == 2)
{
a.steps.push({ action: 'start', info: 'foo' })
}
db.obj.insert(a);
};
此代码创建随机数量的操作。 如果您只需要包含操作的文档数量:' start'然后在查询下方。
db.obj.count({"steps.action":"start"})
我在跑步中得到了计数。
> db.obj.count({"steps.action":"start"})
6756
但是如果您需要在文档中使用{action:' start'},则需要进行聚合查询。 你放松然后匹配
db.obj.aggregate(
[
{ $unwind : "$steps"},
{$match: { "steps.action" : "start" }},
{
$group:
{
_id: null
,count: { $sum: 1 }
}
}
]
)
输出:
{ "_id" : null, "count" : 10054 }
if you get your exception again use **allowDiskUse : true** option. See [here][1].
db.obj.aggregate(
[
....
]
,
{
allowDiskUse : true
}
)