我是一個MongoDb新手。我越來越好,但還沒有專家。我試圖以一種合理的方式設置我的收藏。我想保留一些鏈接到只是_ids數組中的外部文檔以及具有_id的對象數組。
我創建了一個JSON文檔與我想的筆記充分說明什麼,我試圖做...
// (item) Character Inventory/Items collection
[
{
"_id": "1234",
"name": "Sword",
"descr": "Long sword, well worn, light rust",
"encumber": 2,
"del": false
},
{
"_id": "1271",
"name": "Pouch",
"descr": "Small leather waist pouch, suitable for coins",
"encumber": 0,
"del": false
}
]
// (charnpcclass) Character Classes collection
[
{ "_id": "2", "name": "Thief", "del": false },
{ "_id": "3", "name": "Cleric", "del": false }
]
// (charnpcalign) Character Alignments collection
[
{ "_id": "3", "name": "Lawful Good", "del": false },
{ "_id": "4", "name": "Neutral", "del": false }
]
// (character) Characters collection
[
{
"_id": "3345",
"name": "Offut 'Dead Dog' Dubro",
"description": "Halfling, scruffy, looks homeless",
"align": ObjectId("4"),
"classes": [
ObjectId("2"),
ObjectId("3")
],
"carrying": [
{ "itemId": ObjectId("1271"), "qty":1, "where": "Sheath inside vest", "visible": false }
{ "itemId": ObjectId("1234"), "qty":1, "where": "Sword scabbard at waist", "visible": true }
],
"del": false
}
]
// ------------------------------------------------------------
// This is my MongoDb aggregation in the REST api routes
var linkedModels = [
{
"$match": { "del": false }
}, {
"$lookup": {
from: "charnpcclass",
localField: "classes",
foreignField: "_id",
as: "linked_classes"
}
}, {
"$lookup": {
from: "charnpcalign",
localField: "alignId",
foreignField: "_id",
as: "linked_align"
}
}, {
"$lookup": {
from: "item",
localField: "carrying.itemId",
foreignField: "_id",
as: "linked_carrying"
}
}
];
db.collection('character').aggregate(linkedModels).toArray(function (err, docs) {
res.json(201, docs);
next();
});
// Query for Character, return items carrying with data from items collection
// ------------------------------------------------------------
// WHAT I *WANT* IN RESPONSE...
{
"id": "3345",
"name": "Offut 'Dead Dog' Dubro",
"description": "Halfling, scruffy, looks homeless",
"align": "4",
"classes": [
"2",
"3"
],
"carrying": [
{ "itemId": "1271", "qty":1, "where": "Sheath inside vest", "visible": false }
{ "itemId": "1234", "qty":1, "where": "Sword scabbard at waist", "visible": true }
],
"linked_align": [
{ "_id": "4", "name": "Neutral" },
],
"linked_classes": [
{ "_id": "2", "name": "Thief" },
{ "_id": "3", "name": "Cleric" }
],
"linked_carrying": [
{ "_id": "1271", "name": "Dagger", "encumber": 0 },
{ "_id": "1234", "name": "Sword", "encumber": 2 }
]
}
// ------------------------------------------------------------
// WHAT I ACTUALLY GET IN RESPONSE
{
"id": "3345",
"name": "Offut 'Dead Dog' Dubro",
"description": "Halfling, scruffy, looks homeless",
"align": "4",
"classes": [
"2",
"3"
],
"carrying": [
{ "itemId": "1271", "qty":1, "where": "Sheath inside vest", "visible": false }
{ "itemId": "1234", "qty":1, "where": "Sword scabbard at waist", "visible": true }
],
"linked_align": [
{ "_id": "4", "name": "Neutral" },
],
"linked_classes": [],
"linked_carrying": []
}
,我希望你注意到的正上方,在JSON響應例的下面的問題。我的鏈接陣列是空的,我不知道如何解決這個問題。
我將不勝感激您的專家MongoDB的查詢建議:-)
如果你是從一個新的位置「建模」,最好的做法是將外鍵包含在「子」內而不是「父子」內的「子列」。問題在於,對於數組中的對象結構,您不能直接使用'$ lookup'並要求數組上的'$ unwind'來處理(這可能會改變)。如果未正確處理,使用'$ unwind'多個數組可能會導致[笛卡爾積](https://en.wikipedia.org/wiki/Cartesian_product)。由於您不是創建大型數組,因此還需要將外鍵保留在子級中。 –
@NeilLunn如果你的父母恰好與一個孩子有聯繫,這是有道理的。你可以看到我在「對齊」中這樣做。然而,這並不能滿足像我的示例JSON中所示的「類」和/或「攜帶」之類的1:N關係的需要。 – Locohost
我想你是誤會。父'''_id「:」123「}'孩子'{」_id「:1,」parent「:」123「},{」_id「:2,」parent「:」123「}'操作符允許通過使用外鍵來檢索多個或奇異的孩子。在這種情況下,來自孩子的「父母」。這消除了存儲在父數組內的需要。因此'{「$ lookup」:{「from」:「child」,「localField」:「_id」,「foreignField」:「parent」,「as」:「children」}}'。這取決於案件。通過內嵌的文檔和引用,就可以使用'$ unwind'。我會分開rels –