要件は、フィールドがマスクされるようにドキュメントを「投影」することだけなので、そうです、集約フレームワークはこれを行うためのツールです。ただし、アレイを巻き戻したり再構築したりする場合は、プロセスに頭を悩ませるのに少し時間がかかります。
だからあなたが欲しかったのはこれでした:
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<を使用して行うことができます。 / code>
および $ 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」部分があるからです。 code> $ map
オペレーターは、これらの各要素の条件を評価することを期待しています。
$ unwind
および $ group
フィールドを削除するためだけの操作。ですから、それは本当にあなたが期待するかもしれない単なる「投影」になります。