如果我定义了以下模式,如何在更新和删除期间保持集合同步:
var RestaurantSchema = mongoose.Schema({
name: {
type: String,
required: true,
},
menus: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Menu'
}]
});
var MenuSchema = mongoose.Schema({
name: {
type: String,
required: true
},
restaurant: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Restaurant',
required: true
}
});
我通过以下方式创建了一家餐馆:
Restaurant.create(restaurant, callback);
我创建了一个菜单,并通过执行以下操作将其链接到餐厅:
Menu.create(menu, function(err, menu) {
if (err) {
callback(err, menu);
}
else {
restaurantController.addMenu(menu.restaurant, menu._id,
function(err, restaurant) {
callback(err, menu);
});
}
});
第一个问题,是否有更好的方法向餐馆添加菜单?
第二个问题,当我删除菜单或删除餐馆时如何保持数据同步?
第三个问题,当我执行从参考字段中删除id的更新时,如何在集合中保持数据同步。例如,如果我这样做:
Restaurant.findOneAndUpdate({ _id: _id }, { $unset.menus }, options, callback);
这将清空餐厅文档上的菜单数组,但菜单文档仍然会引用餐厅。
答案 0 :(得分:1)
IMO Menu
和Restaurant
应具有单向关系。因此,Restaurant
实体可以引用Menu
(如果餐厅和菜单需要为1-1)或者菜单1-n(早餐,午餐,晚餐等等)的集合。
Menu
无需引用Restaurant
,因为这可能会导致循环引用问题。
此外,数据完整性可能会被搞砸。
例如,如果Restaurant-A
引用了Menu-A
,但Menu-A
引用了Restaurant-B
,该怎么办?
关于你的问题: 第一个问题,是否有更好的方法向餐馆添加菜单?
Menu
,应该返回_id
。 Restaurant
myRestaurant.menuId = _id
。 更新餐厅。
PS:您可以使用promises来平整您的结构。
第二个问题,当我删除菜单或删除餐馆时如何保持数据同步?
您正在查看需要作为交易运行的2 db操作(删除菜单,从餐厅删除菜单参考)。了解如何进行多文档交易 https://docs.mongodb.com/manual/tutorial/perform-two-phase-commits/
我的上述答案可能足以满足您的第三个问题。
这将清空餐厅文档上的菜单数组,但菜单文档仍然会引用餐厅。
如果您将架构重新连接为单向,则不必担心这一点。
希望这有帮助。