Da Ihre Anforderung darin besteht, das Dokument nur zu "projizieren", damit das Feld maskiert wird, ist das Aggregationsframework ein Werkzeug dafür. Es dauert jedoch ein bisschen, bis Sie sich mit dem Prozess vertraut gemacht haben, wenn Sie Arrays abwickeln und rekonstruieren.
Sie wollten also Folgendes:
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" }
}}
])
Aber wirklich, wenn Sie eine Version von MongoDB 2.6 oder höher haben, müssen Sie nicht $unwind
und $group
die Ergebnisse wieder zusammen, um dieses Feld auszulassen. Sie können dies jetzt einfach mit $project
und der $map
Operator, der mit Arrays arbeitet:
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
]
}
}
}
}}
])
Entschuldigung für die Einrückung, die dort ein wenig von der Seite wegscrollt, aber es ist im Vergleich immer noch einfacher zu lesen.
Der erste $map
verarbeitet das Fragen-Array an Ort und Stelle und speist es in einen inneren $map
das die inneren Antworten-Array-Dokumente ohne das Feld „isCorrectAnswer“ zurückgibt. Es verwendet seine eigenen Variablen zur Darstellung der Elemente und die Verwendung von $ifNull
drin ist nur, weil der "in"-Teil von $map
Operator erwartet, eine Bedingung für jedes dieser Elemente auszuwerten.
Insgesamt etwas schneller, da Sie den $unwind
und $group
Operationen, nur um das Feld zu entfernen. Es wird also wirklich nur die "Projektion", die Sie vielleicht erwarten.