Étant donné que votre exigence est simplement de "projeter" le document afin que le champ soit masqué, oui, le cadre d'agrégation est un outil pour le faire. Il faut un peu de temps pour comprendre le processus lors du déroulement des tableaux et de la reconstruction.
Donc, ce que vous vouliez, c'était ceci :
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" }
}}
])
Mais vraiment, si vous avez une version MongoDB 2.6 ou supérieure, vous n'avez pas besoin de $unwind
et $group
les résultats de nouveau ensemble afin d'omettre ce champ. Vous pouvez maintenant le faire en utilisant $project
et le $map
opérateur qui fonctionne avec des tableaux :
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
]
}
}
}
}}
])
Désolé pour l'indentation qui défile un peu sur la page, mais c'est toujours plus facile à lire en comparaison.
Le premier $map
traite le tableau de questions en place et alimente un $map
qui renvoie les documents du tableau de réponses internes sans le champ "isCorrectAnswer". Il utilise ses propres variables pour représenter les éléments et l'utilisation de $ifNull
il y a juste parce que la partie "in" du $map
l'opérateur s'attend à évaluer une condition sur chacun de ces éléments.
Globalement un peu plus rapide, car vous n'avez pas à passer par le $unwind
et $group
opérations juste pour supprimer le champ. Cela devient donc vraiment la "projection" à laquelle vous pourriez vous attendre.