Como seu requisito é apenas "projetar" o documento para que o campo seja mascarado, sim, a estrutura de agregação é uma ferramenta para fazer isso. Demora um pouco para entender o processo ao desenrolar matrizes e reconstruir.
Então o que você queria era isso:
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" }
}}
])
Mas, na verdade, se você tiver uma versão do MongoDB 2.6 ou superior, não precisará
$unwind
e $group
os resultados novamente para omitir esse campo. Agora você pode fazer isso usando $project
e o $map
operador que trabalha com 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
]
}
}
}
}}
])
Desculpe pelo recuo rolando um pouco para fora da página, mas ainda é mais fácil de ler por comparação.
O primeiro
$map
processa a matriz de perguntas no local e alimenta um $map
que retorna os documentos da matriz de respostas internas sem o campo "isCorrectAnswer". Ele usa suas próprias variáveis para representar os elementos e o uso de $ifNull
lá é apenas porque a parte "in" do $map
operador espera avaliar uma condição em cada um desses elementos. No geral, um pouco mais rápido, pois você não precisa passar pelo
$unwind
e $group
operações apenas para remover o campo. Então realmente se torna apenas a "projeção" que você poderia esperar.