mongoid使用相同的mongo“_id”创建2个嵌入式文档

时间:2015-05-06 12:25:20

标签: ruby-on-rails ruby mongodb mongoid

我有一个mongodb记录是否有意义,其中一个字段是两个相同的嵌入文档的数组(即使“_id”是相同的)。

当我使用mongoid创建记录时,我遇到了这个问题。我不太了解mongoid的嵌入式文档实现,但我想如果这些嵌入式文档是“文档”,它们都不应该有另一个文档已经使用的“_id”。

我得到的一个例子:

{
   _id: "123",
   name: "sylvain",
   friends: [ ]
},
{
   _id: "245",
   name: "sonia",
   friends: [ {
      _id: 123,
      name: "sylvain"
   },
   {
      _id: 123,
      name: "sylvain"
   } ]
},
{
   _id: "456",
   name: "bob",
   friends: [ {
      _id: 123,
      name: "sylvain"
   } ]
}

1 个答案:

答案 0 :(得分:3)

为了说清楚:

  • 集合的每个 root 文档上的_id字段是必需。它用于唯一标识您的文档。将其视为您馆藏的主要钥匙。 始终_id字段的索引。
  • 通常,嵌入式文档没有唯一标识符(他们根本不需要:嵌入式文档实际上是其父文档的一部分 - 这不是查看两个“已加入”的集合。)
  • 但是,您可以在嵌入文档中添加id字段作为外键。即使这可能相当令人困惑,如果你愿意,你甚至可以称之为_id。但是在这种情况下它没有任何特殊含义。

由于NoSQL数据库倾向于使用非规范化模式,因此在MongoDB中将相同的文档嵌入到不同的根文档中是很常见的。事实上,这是表达多对多关系的一种方式。

这是一个非常有效的例子(正如我之前所说,使用_id作为字段名称可能会让人一见钟情):

{
   _id: "123",
   name: "sylvain",
   friends: [ ]
},
{
   _id: "245",
   name: "sonia",
   friends: [ {
      _id: 123,
      name: "sylvain"
   } ]
},
{
   _id: "456",
   name: "bob",
   friends: [ {
      _id: 123,
      name: "sylvain"
   } ]
}

关于在相同的父文档中嵌入两个相同的文档:这可能是一种“计算”从父项到子项的引用数的方法。将您的父子文档关系视为图形。您可能从一个节点到另一个节点有两个链接 - 另一方面,可以考虑在嵌入式文档中添加一些“权重”字段(因此,限定链接)。根据您的使用情况,两种解决方案都可能有利有弊。

以下是使用两个不同模型表示以下事实的示例:

  

“客户 sylvain 目前持有两张优惠券,可在我们的商店免费下载MP3

// customer
{
   _id: "123",
   name: "sylvain",
   coupons: [ {
        _id: 9905,
        desc: "Free MP3 download"
   },
   {
        _id: 9905,
        desc: "Free MP3 download"
   } ]
}

或者,人们可能会更多地这样想:

// customer
{
   _id: "123",
   name: "sylvain",
   coupons: [ {
        _id: 9905,
        desc: "Free MP3 download",
        qty: 2
   } ]
}

就我自己而言,我认为如果后者真的比前者更好,那就不那么明显了。例如,在后一种情况下,当客户使用优惠券时,您必须decrease the qty -- and remove the coupon if qty == 0。似乎比前一种情况更有效。但是YMMV。