簡短的回答
這是一個核心的MongoDB的設計決定:MongoDB relationships: embed or reference?
存儲對象的引用,而不是他們的獨立副本,你會在關係數據庫中做的是可能在MongoDB中,經常這樣做,當你需要查看它時,它會導致越來越複雜的查詢。
龍答案
如果目標只是保持成分模式的定義一致,你可以定義一個模式,並使用它兩次。成分將作爲獨立的副本存儲,例如,
[{ username: 'bob',
ingredients: [ { name: 'Carrot', category: 'Vegetable' } , ...],
foods: [ { name: 'Salad', category: 'Lunch', ingredients: [ { name: 'Carrot', category: 'Vegetable'}, ...]}]
}, ...]
var IngredientSchema = new mongoose.Schema({
name: String,
category: String,
});
var UserSchema = new mongoose.Schema ({
username: String,
password: String,
email: String,
foods: [{
name: String,
category: String,
ingredients: [IngredientSchema] // brackets indicates it's an array,
}],
ingredients: [IngredientSchema]
});
或者,你可以參考對象ID配料:
var UserSchema = new mongoose.Schema ({
username: String,
password: String,
email: String,
foods: [{
name: String,
category: String,
ingredients: [mongoose.Schema.Types.ObjectId] // IDs reference individual ingredients,
}],
ingredients: [IngredientSchema]
});
通過明確界定IngredientSchema,每種成分的對象都有自己的ObjectId當它被宣佈。存儲配料的ID(而不是配料對象的副本)的好處是更簡潔和一致的存儲。缺點是會有更多更復雜的查詢。
[{ username: 'bob',
ingredients: [ { _id: ObjectId('a298d9ef898afc98ddf'), name: 'Carrot', category: 'Vegetable' } , ...],
foods: [ { name: 'Salad', category: 'Lunch', ingredients: [ {$oid: 'a298d9ef898afc98ddf'}, ]}]
}, ...]
,如果你想存儲成分引用一個更好的辦法,可能是配料店作爲自己的頭等集合。如果你想按成分查找食物或食物中的成分,你仍然會有許多單獨的查詢,但查詢會更簡單。
var UserSchema = new mongoose.Schema ({
username: String,
password: String,
email: String,
foods: [{
name: String,
category: String,
ingredients: [mongoose.Schema.Types.ObjectId] // IDs reference individual ingredients,
}],
ingredients: [mongoose.Schema.Types.ObjectId]
});
如果目標是基於它們的成分和搜索食品商店標準化引用,引用另一[SO帖] [1],「這是那些情況下,關係型數據庫大放異彩一個」
看到這個SO張貼憑身份證查詢子文檔: Reading categories and number of articles in a single query
一位受訪者指出,「這是那些情況下,關係型數據庫大放異彩一個」
這是否意味着我必須創建兩個模式,如果我想使用引用而不是嵌入?我最初的想法是保持用戶模式下的成分字段,因爲每個用戶都可以定義他們自己的一組成分。現在使用新的IngredientSchema,我將在一個模式(集合)下存儲來自所有用戶的成分。這不是我所需要的。沒有其他方法嗎? – finspin
此外,試圖理解你爲什麼建議參考foods.ingredients領域和配料領域的IngredientSchema。你能解釋一下給我嗎? – finspin
在我給出的例子中,只有一種配料模式,但配料對象在每種食物中獨立存儲,因爲副本不是參考。但我看到你想通過ID來引用成分而不是重複。將編輯上面的答案... – prototype