我见过kind of a similar question,但是它没有答案,因此无法回答我的问题。
如何在mongodb聚合中基于另一个数组对数组进行分组?
假设您具有以下架构:
PollSchema
const PollSchema = new mongoose.Schema({
numberOfChoices: {
type: Number,
required: true,
min: [1, "Number of choices must be at least 1"],
max: [10, "Number of choices cannot be more than 10"],
},
arrayOfNamesOfChoices:[{
name: {
type: String,
required: true,
},
}],
});
CastedVotedSchema
const CastedVoteSchema = new mongoose.Schema({
voter: {
type: String,
required: true,
},
choice: {
type: Number,
required: true,
min:0,
max:9
},
});
在mongodb聚合中,我如何根据选择的数组对castedVote进行排序。例如,考虑以下数据示例:
Poll = {
numberOfChoices: 3
arrayOfNamesOfChoices: [
{name:'choiceA'},{name:'choiceB'},{name:'choiceC'}
]
}
CastedVotes = [
{voter: 'Juzi', choice: 0},{voter: 'Juma', choice: 0},{voter: 'Jane', choice: 0},
{voter: 'Jamo', choice: 1},{voter: 'Juju', choice: 1},{voter: 'Jana', choice: 1},
]
注意:choiceC
中没有投票
我正在尝试创建一个聚合查询,该查询将根据每个选择返回一个数组。例如(见下文)。
//below is the result I desire to have
{
totalVotes:[
{voter: 'Juzi', choice: 0},{voter: 'Juma', choice: 0},{voter: 'Jane', choice: 0},
{voter: 'Jamo', choice: 1},{voter: 'Juju', choice: 1},{voter: 'Jana', choice: 1},
],
choiceA:[{voter: 'Juzi', choice: 0},{voter: 'Juma', choice: 0},{voter: 'Jane', choice: 0}],
choiceB:[{voter: 'Jamo', choice: 1},{voter: 'Juju', choice: 1},{voter: 'Jana', choice: 1}],
choiceC:[],// the choiceC array should be present and empty
}
如何在mongodb聚合中将基于CastedVote
的{{1}}数组分组?
答案 0 :(得分:1)
如何在mongodb聚合中将基于CastedVote数组的Poll.arrayOfNamesOfChoices数组分组?
如果您有一个名为poll
的集合,其中包含如下文档
{ "_id": 100,
"choices": [
{ "name": "choiceA", "id": 0 },
{ "name": "choiceB", "id": 1 },
{ "name": "choiceC", "id": 2 } ]
}
另一个名为castedvote
的集合,其中包含以下文档:
{"voter": "Juzi", "choice": 0, "pollId": ObjectId("...")}
{"voter": "Juma", "choice": 0, "pollId": ObjectId("...")}
{"voter": "Jane", "choice": 0, "pollId": ObjectId("...")}
{"voter": "Jamo", "choice": 1, "pollId": ObjectId("...")}
{"voter": "Juju", "choice": 1, "pollId": ObjectId("...")}
{"voter": "Jana", "choice": 1, "pollId": ObjectId("...")}
您可以在下面执行聚合:
db.poll.aggregate([
{"$match": {"_id": 100}},
{"$unwind":"$choices"},
{"$lookup": {
"from":"castedvotes",
"let": {"c":"$choices"},
"pipeline":[
{"$match":
{"$expr":
{"$eq": ["$choice", "$$c.id"]},
}},
],
"as":"voters"
}},
{"$addFields":{
"x": {
"$arrayToObject": [ [{"k": "$choices.name", "v": "$voters"}] ]
}
}},
{"$replaceRoot": {"newRoot": "$x"}},
]);
使用$arrayToObject根据字段值创建动态字段名。输出为:
{ "choiceA": [
{"_id": ObjectId("..."), "voter": "Juzi", "choice": 0, "pollId": 100 },
{"_id": ObjectId("..."), "voter": "Juma", "choice": 0, "pollId": 100 },
{"_id": ObjectId("..."), "voter": "Jane", "choice": 0, "pollId": 100 },
]},
{ "choiceB": [
{"_id": ObjectId("..."), "voter": "Jamo", "choice": 1, "pollId": 100 },
{"_id": ObjectId("..."), "voter": "Juju", "choice": 1, "pollId": 100 },
{"_id": ObjectId("..."), "voter": "Jana", "choice": 1, "pollId": 100 }
]},
{ "choiceC": [ ] }