MongoDB - $ ricerca in un array annidato complesso
Sto costruendo un nuovo LMS in mongodb e ho le seguenti raccolte:
Corsi
{
"_id": ObjectId("5f6a6b159de1304fb885b194"),
"title": "Course test",
"sections": [
{
"_id": ObjectId("5f6a6b159de1304fb885b195"),
"title": "Section 1 - introduction",
"order": 1,
"modules": [
{
"_id": ObjectId("5f6a6b159de1304fb885b196"),
"module_FK_id": ObjectId("5f6a6b149de1304fb885b135"),
"title": "Module 1",
"order": 1
},
{
"_id": ObjectId("5f6a6b159de1304fb885b198"),
"module_FK_id": ObjectId("5f6a6b149de1304fb885b14a"),
"title": "Module 2",
"order": 2
},
]
},
{
"_id": ObjectId("5f6a6b149de1304fb885b175"),
"title": "Section 2 - How to do something",
"order": 2,
"modules": [
{
"_id": ObjectId("5f6a6b149de1304fb885b141"),
"module_FK_id": ObjectId("5f6a6b149de1304fb885b150"),
"title": "Module 1",
"order": 1
},
{
"_id": ObjectId("5f6a6b149de1304fb885b15f"),
"module_FK_id": ObjectId("5f6a6b149de1304fb885b18e"),
"title": "Module 2",
"order": 2
},
]
},
]
}
Moduli (solo uno come esempio)
{
"_id": ObjectId("5f6a6b149de1304fb885b135"),
"text": "Lorem ipsum...",
"mediaUrl": "urllinkhere"
}
Come mostrato, scelgo di avere documenti incorporati per sezioni e titoli di moduli, ma ho bisogno anche di una seconda raccolta, moduli, perché ogni modulo contiene una grande quantità di testo e il mio documento di corso potrebbe diventare troppo grande rapidamente.
Ora ho bisogno di ricostruire l'intero documento come se fosse completamente incorporato. Ecco un esempio:
{
"_id": ObjectId("5f6a6b159de1304fb885b194"),
"title": "Course test",
"sections": [
{
"_id": ObjectId("5f6a6b159de1304fb885b195"),
"title": "Section 1 - introduction",
"order": 1,
"modules": [
{
"_id": ObjectId("5f6a6b159de1304fb885b196"),
"module_FK_id": ObjectId("5f6a6b149de1304fb885b135"),
"title": "Module 1",
"order": 1
"text": "Lorem ipsum...",
"mediaUrl": "urllinkhere"
},
// last two fields from collection "modules"
Sto provando una combinazione diversa di aggregazione e ricerche ma non riesco a ottenere il risultato desiderato.
Qualcuno può aiutarmi?
Risposte
Puoi costruire la pipeline di aggregazione come questa di seguito, just remember to $ group in the reverse order of $ rilassarsi operations
db.courses.aggregate([
{
$unwind: "$sections"
},
{
$unwind: "$sections.modules"
},
{
"$lookup": { "from": "modules", "localField": "sections.modules.module_FK_id", "foreignField": "_id", "as": "module_details" } }, { $unwind: {
path: "$module_details", preserveNullAndEmptyArrays: true } }, { "$project": {
title: 1,
sections: {
_id: "$sections._id", modules: { _id: "$sections.modules._id",
module_FK_id: "$sections.modules.module_FK_id", order: "$sections.modules.order",
title: "$sections.modules.title", mediaUrl: "$module_details.mediaUrl",
text: "$module_details.text" }, order: "$sections.order",
title: "$sections.title" } } }, { "$group": {
"_id": "$sections._id", main_id: { $first: "$_id" }, main_title: { $first: "$title" }, order: { $first: "$sections.order" }, title: { $first: "$sections.title" }, modules: { $push: "$sections.modules" } } }, { "$project": {
"_id": "$main_id", "title": "$main_title",
section: {
_id: "$_id", modules: "$modules",
title: "$title", order: "$order",
}
}
},
{
$group: { _id: "$_id",
title: {
$first: "$title"
},
sections: {
$push: "$section"
}
}
}
])
Esempio di lavoro