Da dit krav er bare at "projektere" dokumentet, så feltet er maskeret, ja aggregeringsrammen er et værktøj til at gøre dette. Det kræver dog lidt at få styr på processen, når du afvikler arrays og rekonstruerer.
Så det, du ønskede, var dette:
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" }
}}
])
Men virkelig, hvis du har en MongoDB 2.6 eller nyere version, behøver du ikke $unwind
og $group
resultaterne sammen igen for at udelade dette felt. Du kan nu bare gøre dette ved at bruge $project
og $map
operator, der arbejder med arrays:
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
]
}
}
}
}}
])
Beklager, at indrykket ruller lidt af siden der, men det er stadig lettere at læse ved sammenligning.
Den første $map
behandler spørgsmålsarrayet på plads og feeds til en indre $map
der returnerer de indre svar-array-dokumenter uden feltet "isCorrectAnswer". Den bruger sine egne variabler til at repræsentere elementerne og brugen af $ifNull
der er bare fordi "in"-delen af $map
operatør forventer at evaluere en betingelse på hvert af disse elementer.
Samlet set lidt hurtigere, da du ikke behøver at gå gennem $unwind
og $group
operationer bare for at fjerne feltet. Så det bliver i virkeligheden bare den "projektion", som du kunne forvente.