Vzhledem k tomu, že vaším požadavkem je pouze „promítnout“ dokument, aby bylo pole maskováno, ano, agregační rámec je nástroj, jak to udělat. Trochu to trvá, než se zorientujete v procesu při odvíjení polí a rekonstrukci.
Takže to, co jste chtěli, bylo toto:
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" }
}}
])
Ale opravdu, pokud máte MongoDB 2.6 nebo vyšší verzi, nemusíte $unwind
a $group
výsledky zpět dohromady, aby bylo možné toto pole vynechat. Nyní to můžete udělat pomocí $project
a $map
operátor, který pracuje s poli:
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
]
}
}
}
}}
])
Omlouvám se za odsazení, které se trochu posouvá mimo stránku, ale ve srovnání s tím je to stále lépe čitelné.
První $map
zpracuje pole otázek na místě a odešle je do vnitřního $map
který vrací dokumenty s vnitřním polem odpovědí bez pole "isCorrectAnswer". K reprezentaci prvků používá své vlastní proměnné a použití $ifNull
je tam jen proto, že "in" část $map
operátor očekává, že vyhodnotí podmínku každého z těchto prvků.
Celkově o něco rychlejší, protože nemusíte procházet přes $unwind
a $group
operace jen k odstranění pole. Takže se to skutečně stane jen "projekcí", kterou byste mohli očekávat.