我是一个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 –