如何在一个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字段投影到10而不是truefalse
还是有一个完整的,更好的方法? 🙂

我想避免进行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 }