如何使用MongoDB维护文档之间的完整性?

时间:2015-10-11 17:56:59

标签: mongodb

我正在编写一个应用程序,我想使用MongoDB。在过去,我一直使用关系数据库。 我不明白如何保持诚信。我用一个例子更好地解释了我:

我有“餐馆”,“菜肴”和“食材”。如果我在MongoDB中为一个菜创建一个文件,它有很多成分(对象“成分”的数组)。我还收集了所有食材。

如果我更改配料名称,如何将配料名称更新为“菜肴”文件?

1 个答案:

答案 0 :(得分:1)

您的描述听起来像是一个人为的例子,因此有点难以正确回答,但我现在还会坚持下去。

在您的示例中,问问自己真的是否需要独特的成分。用户如何添加新的?他或她是否必须首先搜索成分集合?在您的数据库中有两到三个甜椒实例时,真的会有所不同吗?怎么样的限定词(如“猪里脊”或“爪哇香草”或“英国切达干酪”)。那可用性怎么样?

NoSQL方法将是

  啊,搞砸了!让我们建议以前输入的其他用户的成分。如果用户选择一个,那很好。否则,即使每道菜都有自己的配料清单,也没关系。它最多会积累到几个megs。

所以,你完全放弃了原料系列并提出了一个新的模型:

{
  _id: someObjectId,
  name: "Sauerbraten",
  ingredients: [
    {name: "cap of beef rump", qty: "1 kg"},
    {name: "sugar beet syrup", qty: "100ml"},
    {name: "(red) wine vinegar", qty: "100 ml"}
    {name: "onions", qty: "2 large" },
    {name: "carrots", qty: "2 medium"}
    // And so on
  ]
}

因此,您不再需要参照完整性。而且您可以自由地让用户对成分进行鉴定。现在,您将如何创建成分建议?非常简单:偶尔运行聚合。

db.dishes.aggregate([
  {"$unwind":"$ingredients"},
  {"$group": {"_id":"$ingredients.name","dishes":{"$addToSet":"$_id"} }},
  {"$out":"ingredients"}
])

产生一个名为成分的集合,默认情况下将成分的名称编入索引(因为它们是_id)。因此,如果用户输入新成分,您可以建议自动完成。鉴于用户输入“牛肉”,您的查询将如下所示:

db.ingredients.find({"_id": /beef/i})

应返回

{ "_id": "cap of beef rump", "dishes": [ someObjectId ]}

因此,如果没有参照完整性,您可以使应用程序更易于使用,维护甚至添加一些基本免费的功能。