Тъй като вашето изискване е просто да „проектирате“ документа, така че полето да е маскирано, да, рамката за агрегиране е инструмент за извършване на това. Отнема малко време, за да се ориентирате в процеса, когато развивате масиви и реконструирате.
И така, това, което искахте, беше следното:
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" }
}}
])
Но наистина, ако имате MongoDB 2.6 или по-нова версия, тогава не е необходимо да $unwind
и $group
резултатите отново заедно, за да пропуснете това поле. Вече можете просто да направите това, като използвате $projectкод>
и $map
оператор, който работи с масиви:
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
]
}
}
}
}}
])
Съжалявам за вдлъбнатината, която се превърта малко извън страницата там, но все пак е по-лесна за четене в сравнение.
Първият $map
обработва масива с въпроси на място и се подава към вътрешен $map
който връща документите с вътрешния масив с отговори без полето "isCorrectAnswer". Той използва свои собствени променливи за представяне на елементите и използването на $ifNull
там е само защото частта "in" на $map
операторът очаква да оцени условие за всеки от тези елементи.
Като цяло малко по-бързо, тъй като не е нужно да преминавате през $unwind
и $group
операции само за премахване на полето. Така че наистина се превръща в „проекцията“, която може да очаквате.