2016-06-11 55 views
0

如何保持同步收藏更新和刪除過程中,如果我已經定義了以下的模式:貓鼬和數據完整性

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); 
      }); 
    } 
}); 

第一個問題,有沒有更好的wa ❖向餐館添加菜單?

第二個問題,當我刪除菜單或刪除餐館時,如何保持數據同步?

第三個問題,當我執行更新以從參考字段中刪除ID時,如何保持數據在集合中同步。例如,如果我這樣做:

Restaurant.findOneAndUpdate({ _id: _id }, { $unset.menus }, options, callback); 

這將清空對餐飲文件菜單排列,但是,菜單文件將仍然有參考餐廳。

回答

1

IMO MenuRestaurant應該具有單向關係。因此,一個Restaurant實體可以參考Menu(如果餐廳和菜單需要1-1)或一組菜單1-n(早餐,午餐,晚餐等)。

A Menu不需要返回Restaurant,因爲這可能導致循環參考問題。

此外,數據的完整性可能會被破壞。 例如,如果Restaurant-A引用Menu-A,但Menu-A引用Restaurant-B會怎麼樣?

關於您的問題: 第一個問題,有沒有更好的方法來添加菜單的餐館?

  1. 創建一個Menu,應該回報你_id
  2. 將該參考文獻添加到RestaurantmyRestaurant.menuId = _id
  3. 更新餐廳。 PS:你可以用promise來代替你的結構。

第二個問題,當我刪除菜單或刪除餐館時,如何保持數據同步?

您正在查看需要作爲事務運行的2分貝操作(刪除菜單,從菜單中刪除菜單引用)。結帳如何做多文件交易 https://docs.mongodb.com/manual/tutorial/perform-two-phase-commits/

我上面的答案可能就足夠了你的第三個問題。

這將清空餐廳文檔上的菜單數組,但是菜單文檔仍然會引用餐廳。

如果您將您的架構重新定向爲單向,那麼您不必擔心這一點。

希望這會有所幫助。

+0

我認爲單向模式是一種可行的方法。我對這一切都很陌生,從我一直在閱讀的內容看來,MongoDB的推薦/最佳實踐方法似乎是嘗試將整個文檔放在一個記錄中。但它支持文檔引用,並且使用Mongoose,還有填充方法。所以我想我應該按照我描述的方式創建模式,因爲那樣我可以簡單地使用填充來構建整個文檔,因爲相關的id存儲在數組屬性中。如果遇到像這樣的問題,填充方法的意義何在? –

+0

也許它超出了OP問題的範圍;但是你能否展示一個例子:「你可以使用承諾平滑你的結構」,也就是說,如果你指的是控制器級別的異步/等待以外的東西。我也是Node/Mongoose的新手。 – mrClean