如何在一个MongoDB集合(使用mongoose)中总结一个字段的不同值
想象一下,我有一个名为期刊的集合,其中包含以下文档:
{ "article": "id1", "d": 2 }, { "article": "id1", "d": 2 }, { "article": "id1", "d": 3 }, { "article": "id2", "d": 2 }, ...
其中d是一种开关, 文章是一个参考。 现在我想要得到如下结果:
[ { "_id": "id1", "total": 3, "d2": 2, "d3": 1 }, { "_id": "id2", "total": 1, "d2": 1, "d3": 0 } ]
我正在使用mongoose,并有一个名为“ 日记”的模型。 我到目前为止是…
Journal.aggregate( { $project: { articleId: 1, depth2 : { $gte:['$d', 2] }, depth3 : { $eq:['$d', 3] } }}, { $group: { _id: '$article', total: { $sum: 1 }, d2: { $sum: '$depth2'}, d3: { $sum: '$depth3'} } }, function (err, journal) { console.log(journal); } );
这导致:
[ { "_id": "id1", "total": 3, "d2": 0, "d3": 0 }, { "_id": "id2", "total": 1, "d2": 0, "d3": 0 } ]
很显然,这里的错误是$eq:['$d', 3]
没有被总结,因为这会导致一个布尔值。
那么是否有更好的expression式将新的depth2和depth3字段投影到1
或0
而不是true
或false
?
还是有一个完整的,更好的方法? 🙂
我想避免进行3个查询,并预先匹配{ $match: { d: 2 } }
这样的匹配阶段。
您可以使用$cond
将布尔值转换为数字值,但您也得到$gte
,看起来$eq
应该是,而您的文档在您的代码使用articleId
时使用了articleId
:
Journal.aggregate([ { $project: { article: 1, depth2 : { $cond: [{$eq: ['$d', 2]}, 1, 0] }, depth3 : { $cond: [{$eq: ['$d', 3]}, 1, 0] } }}, { $group: { _id: '$article', total: { $sum: 1 }, d2: { $sum: '$depth2'}, d3: { $sum: '$depth3'} } } ]);
输出:
{ "result" : [ { "_id" : "id2", "total" : 1, "d2" : 1, "d3" : 0 }, { "_id" : "id1", "total" : 3, "d2" : 2, "d3" : 1 } ], "ok" : 1 }