Aangezien het uw vereiste is om het document gewoon te "projecteren", zodat het veld wordt gemaskeerd, is het aggregatieraamwerk inderdaad een hulpmiddel om dit te doen. Het kost wat tijd om je hoofd rond het proces te krijgen bij het afwikkelen van arrays en het reconstrueren.
Dus wat je wilde was dit:
db.collection.aggregate([
{ "$unwind": "$questions" },
{ "$unwind": "$questions.answers" },
{ "$group": {
"_id": {
"_id": "$_id",
"name": "$name",
"description": "$description",
"qid": "$questions._id",
"question": "$questions.question"
},
"answers": {
"$push": {
"_id": "$questions.answers._id",
"answer": "$questions.answers.answer"
}
}
}},
{ "$project": {
"questions": {
"_id": "$_id.qid",
"question": "$_id.question",
"answers": "$answers"
}
}},
{ "$sort": { "_id": 1, "questions._id": 1 } },
{ "$group": {
"_id": "$_id._id",
"name": { "$first": "$_id.name" },
"description": { "$first": "$_id.description" },
"questions": { "$push": "$questions" }
}}
])
Maar echt, als je een MongoDB 2.6 of hogere versie hebt, hoef je niet $unwind
en $group
de resultaten weer bij elkaar om dat veld weg te laten. Je kunt dit nu gewoon doen met $project
en de $map
operator die met arrays werkt:
db.collection.aggregate([
{ "$project": {
"name": 1,
"description": 1,
"questions": {
"$map": {
"input": "$questions",
"as": "q",
"in": {
"$ifNull": [
{
"_id": "$$q._id",
"question": "$$q.question",
"answers": {
"$map": {
"input": "$$q.answers",
"as": "el",
"in": {
"$ifNull": [
{ "_id": "$$el._id", "answer": "$$el.answer" },
false
]
}
}
}
},
false
]
}
}
}
}}
])
Sorry voor de inspringing die daar een beetje van de pagina rolt, maar het is nog steeds gemakkelijker te lezen in vergelijking.
De eerste $map
verwerkt de vragenreeks op zijn plaats en feeds naar een innerlijke $map
die de innerlijke antwoorden-array-documenten retourneert zonder het veld "isCorrectAnswer". Het gebruikt zijn eigen variabelen om de elementen weer te geven, en het gebruik van $ifNull
daar zit alleen maar in omdat het "in" deel van de $map
de operator verwacht een voorwaarde voor elk van deze elementen te evalueren.
Over het algemeen een beetje sneller, omdat je niet door de $unwind
en $group
bewerkingen om het veld te verwijderen. Het wordt dus echt de "projectie" die je zou verwachten.