这是我正在使用的基本abtract架构:
var activity = {
_id: ObjectId,
occurrences: [{
_id: ObjectId,
date: Date,
followers: [ ObjectID ],
attendances: [{
answer: String
}]
}]
}
示例文件:
var activity = {
_id: '123',
occurrences: [{
_id: '111',
followers: [
'777',
'888'
],
attendances: [{
answer: 'yes'
}, {
answer: 'no'
}]
}, {
_id: '222',
followers: [
'555',
'666'
],
attendances: [{
answer: 'yes'
}, {
answer: 'yes'
}]
}]
}
使用聚合管道我想将其分解为单独的事件,每个事件包含其答案与字符串匹配的出勤次数(即"是")。我可以将事情分解为个别事件但是在进一步崩溃时遇到困难。结果正确显示每次出现的次数,但是追随者数量是完全错误的。我可能让事情变得更加复杂,我也需要:
这是我的非工作尝试:
this.aggregate({
$unwind: '$occurences'
}, {
$group: {
_id: '$occurences._id',
attendances: {
$first: "$occurences.attendances"
},
followers: {
$first: "$occurences.followers"
},
}
}, {
$unwind: '$attendances'
}, {
$match: {
"attendances.answer": {
$ne: "no"
}
}
}, {
$group: {
_id: '$_id',
attendances: {
$sum: 1
},
followers: {
$sum: {
$size: {
$ifNull: ["$followers", []]
}
}
}
}
}, {
$project: {
attendances: 1,
followers: 1,
}
}
);
我想要这个结果:
[{ _id: 111, attendances: 1, followers: 2 },
{ _id: 222, attendances: 2, followers: 2 }]
答案 0 :(得分:0)
通过使用$size运算符来获取关注者计数,您可以使查询更简单一些。您仍然需要展开考勤数组以过滤掉“否”答案,然后分组以获得考勤人数。
db.coll.aggregate([
{
$unwind: "$occurrences"
},
{
$project : {
_id : 1,
occurrenceId : "$occurrences._id",
followers: { $size: "$occurrences.followers" },
attendances : "$occurrences.attendances"
}
},
{
$unwind: "$attendances"
},
{
$match: {
"attendances.answer": "yes"
}
},
{
$group: {
_id: { id: "$_id", occurrenceId : "$occurrenceId"},
followers : { $first : "$followers" },
attendances: {
$sum: 1
}
}
}]);
修改强>
我使用您的示例文档的结果是:
{"_id": { "id": "123", "occurrenceId": "222" }, "followers": 2, "attendances": 2}
{"_id": { "id": "123", "occurrenceId": "111" }, "followers": 2, "attendances": 1}
答案 1 :(得分:0)
好的想通了。跟随者计数错误,因为参与者的展开操作创建了多个条目,每个条目都有相同的关注者。而不是使用$ sum来添加它们,我需要使用$ avg。
this.aggregate({
$unwind: '$occurences'
}, {
$group: {
_id: '$occurences._id',
attendances: {
$first: "$occurences.attendances"
},
followers: {
$first: "$occurences.followers"
},
}
}, {
$unwind: '$attendances'
}, {
$match: {
"attendances.answer": {
$ne: "no"
}
}
}, {
$group: {
_id: '$_id',
attendances: {
$sum: 1
},
followers: {
$avg: {
$size: {
$ifNull: ["$followers", []]
}
}
}
}
}
);