猫鼬子文档VS嵌套模式

问题描述:

我很好奇的优点和使用子文档VS更深一层在我的主要模式的利弊:猫鼬子文档VS嵌套模式

var subDoc = new Schema({ 
    name: String 
}); 

var mainDoc = new Schema({ 
    names: [subDoc] 
}); 

var mainDoc = new Schema({ 
    names: [{ 
    name: String 
}] 
}); 

我目前使用各地的小组,但我主要想知道性能或查询我可能遇到的问题。

+0

我想输入一个答案给你,但我找不到如何。但请看看这里:http://mongoosejs.com/docs/subdocs.html – gustavohenke 2013-03-04 20:26:44

+0

下面是关于MongoDB注意事项的一个很好的回答,以便在创建数据库模式时自问:http:// stackoverflow。com/questions/5373198/a-simple-mongodb-question-embed-or-reference – anthonylawson 2013-03-04 20:41:40

+0

你的意思是它还需要描述'_i​​d'字段?我的意思是,如果启用它不是自动的? – Vadorequest 2014-02-08 19:02:46

根据the docs,它是完全一样的。 但是,使用Schema也会添加一个_id字段(只要您没有禁用),并且可能会使用一些更多的资源来跟踪subdoc。

替代声明语法

新的V3如果您不需要访问子文档模式实例,你也可以通过简单地传递对象字面[声明子文档。 ..]

+0

但我尝试过。为什么子文档数据不存储在单独的集合中。它总是存储在mainDoc集合中。 – 2013-05-27 11:13:53

+16

这就是子文件的工作方式。它们嵌入在文档中。在玩猫鼬之前,请确保您了解底层的MongoDB。 – AndyL 2013-05-31 17:06:00

+1

关于模式添加_id,这是有道理的,但我创建了一个具有一个子文档数组和一个对象文字数组的模式,并且_id被添加到两者。行为改变了吗? – 2016-05-03 17:12:11

我认为这是由SO上的多个帖子在别处处理的。

几个:

最大的关键是,没有一个统一的答案在这里,只有一套相当复杂的权衡。

+1

也许我没有正确解释我的问题 - 这不是我应该如何构建数据库的问题,而是使用子模式的内部结构而不是将数组写入更深层的问题。我使用subschema的主要原因是我可以使用自定义模式类型并让它们验证 - 这与嵌套数组无关(来自之前的问题)。就像我可以告诉一个subdoc几乎和嵌套数组一样 - 我只是不知道它的内部 - 如果使用它们会产生性能问题或类似问题。 – cyberwombat 2013-03-04 23:44:43

如果你在你的模型中的各个部分被重新使用的模式,那么它可能是有用的定义各个模式对儿童的文档,这样你就不必重复自己。

+2

这是一个很好的答案。有时我会在多个模型中使用子文档,或者需要区分模型中的两个字段,但仍然具有相同的子文档结构。 – 2014-07-09 09:17:02

+1

你还应该考虑保存冗余信息的好处/缺点。 – 2014-11-24 09:37:34

如果这些文档是静态文档或者由于性能影响而不超过几百个,则应使用嵌入式文档。我刚才已经讨论过这个问题。最近,作为MongoDB解决方案架构师的Asya Kamsky写了一篇关于“使用子文档”的文章。

我希望这有助于谁在寻找解决方案或最佳实践。

原始帖子在http://askasya.com/post/largeembeddedarrays。 您可以在https://stackoverflow.com/users/431012/asya-kamsky

首先,找到她的个人资料计算器,我们要考虑我们为什么会想要做这样的事情 。通常,我建议人们嵌入他们在获取此文档时始终想要返回的东西。这方面的翻转 是你不想在文件 中嵌入你不想回头的东西。

如果嵌入我执行到文档中的活动,它会在 第一工作的伟大,因为我所有的活动都是在那里与一个单一的阅读 你可以回到你可能想要的一切告诉我:“你最近 点击这里,这里是你的最后两条评论“但发生了什么 六个月过去了,我不在乎我做了很长一段时间的事情 以前,你不想让他们看我,除非我专门去 找一些老的活动?

首先,你将最终返回越来越大的文件,并关注 关于它的越来越小的部分。但是你可以使用投影到 只返回一些数组,真正的痛苦是 磁盘上的文件会变大,它仍然会全部被读取,即使你只有 会把它的一部分返回到最后用户,但由于我的活动是 不会停止,只要我活跃,该文件将继续 增长和增长。

最明显的问题是最终你会遇到16MB的 文件限制,但这并不是你应该关注的 。随着文档不断增长,每次需要重新定位到磁盘上时都会产生越来越高的成本,并且即使采取 步骤来减轻碎片效应,您的写入总数也会不必要地太长,从而影响您的整体性能 整个应用程序。

还有一件事你可以完全杀死你的 应用程序的性能,这是索引这个不断增加的 阵列。这意味着每次重新定位此阵列的文档 时,需要更新的索引条目的数量与 中索引值的数量成正比,并且数组越大,数组越大该号码将为 。

我不希望这从使用数组吓唬你,当他们是一个很好的 适合数据模型 - 他们是文档 数据库的数据模型的一个强大的功能,但像所有强大的工具,它需要在正确的情况下使用 ,应谨慎使用。

+0

这应该是最好的答案;这是钱的问题。 MongoDB自己的白皮书说的几乎是一回事。 – 2017-09-13 21:22:01

基本上,创建一个变量nestedDov,并把它放在这里name: [nestedDov]

简单的版本:

var nestedDoc = new Schema({ 
    name: String 
}); 

var mainDoc = new Schema({ 
    names: [nestedDoc] 
}); 

JSON例

{ 
    "_id" : ObjectId("57c88bf5818e70007dc72e85"), 
    "name" : "Corinthia Hotel Budapest", 
    "stars" : 5, 
    "description" : "The 5-star Corinthia Hotel Budapest on the Grand Boulevard offers free access to its Royal Spa", 
    "photos" : [ 
     "/photos/hotel/corinthiahotelbudapest/1.jpg", 
     "/photos/hotel/corinthiahotelbudapest/2.jpg" 
    ], 
    "currency" : "HUF", 
    "rooms" : [ 
     { 
      "type" : "Superior Double or Twin Room", 
      "number" : 20, 
      "description" : "These are some great rooms", 
      "photos" : [ 
       "/photos/room/corinthiahotelbudapest/2.jpg", 
       "/photos/room/corinthiahotelbudapest/5.jpg" 
      ], 
      "price" : 73000 
     }, 
     { 
      "type" : "Deluxe Double Room", 
      "number" : 50, 
      "description" : "These are amazing rooms", 
      "photos" : [ 
       "/photos/room/corinthiahotelbudapest/4.jpg", 
       "/photos/room/corinthiahotelbudapest/6.jpg" 
      ], 
      "price" : 92000 
     }, 
     { 
      "type" : "Executive Double Room", 
      "number" : 25, 
      "description" : "These are amazing rooms", 
      "photos" : [ 
       "/photos/room/corinthiahotelbudapest/4.jpg", 
       "/photos/room/corinthiahotelbudapest/6.jpg" 
      ], 
      "price" : 112000 
     } 
    ], 
    "reviews" : [ 
     { 
      "name" : "Tamas", 
      "id" : "/user/tamas.json", 
      "review" : "Great hotel", 
      "rating" : 4 
     } 
    ], 
    "services" : [ 
     "Room service", 
     "Airport shuttle (surcharge)", 
     "24-hour front desk", 
     "Currency exchange", 
     "Tour desk" 
    ] 
} 

例子:

enter image description here

+0

这并不能解决所有这些问题中的一个问题。 – cyberwombat 2016-09-02 16:34:20

+0

我编辑了一下,以便更有意义。你怎么看? – 2016-09-02 20:32:19

+1

问题不在于如何做嵌套模式。它讨论了Mongoose是否更适合使用嵌套模式或嵌入式子文档。基本上我们正在谈论基准或排序或边缘情况,其中猫鼬喜欢彼此。正如所选答案提到,它至少从V3开始似乎没有任何区别。 – cyberwombat 2016-09-02 21:50:58