想象一下,我有一个名为 journals 的集合,其中包含以下文档:
{
"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 的模型。到目前为止我得到的是......
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]
未被总结,因为这会导致布尔值。
那么是否有更好的表达式将新的depth2和depth3字段投影到1
或0
而不是true
或false
?
或者是否有完整而更好的方法? :)
我希望避免进行3次查询,并在{ $match: { d: 2 } }
之前添加匹配阶段。
答案 0 :(得分:2)
您可以使用$cond
将布尔值转换为数字值,但您还有一个$gte
$eq
应该是article
并且您的文档使用{ {1}}代码使用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
}