javascript - Mongoose子文档与嵌套模式

我很好奇在我的主模式中使用子文档与更深层的优缺点:

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

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

要么

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

我现在到处都在使用subdocs,但我主要想知道性能或查询我可能会遇到的问题。

cyberwombat asked 2019-07-15T23:46:42Z
5个解决方案
56 votes

根据文档,它完全相同。但是,使用Schema也会添加一个_id字段(只要你没有禁用它),并且可能会使用更多资源来跟踪subdocs。

备用声明语法

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

AndyL answered 2019-07-15T23:47:09Z
32 votes

如果您有在模型的各个部分中重复使用的模式,那么为子文档定义单独的模式可能很有用,因此您不必自己复制。

sonstone answered 2019-07-15T23:47:33Z
18 votes

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

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

原帖[http://askasya.com/post/largeembeddedarrays]。您可以访问[https://stackoverflow.com/users/431012/asya-kamsky]上的stackoverflow配置文件

首先,我们必须考虑为什么我们想要这样做   事情。 通常情况下,我会建议人们嵌入他们的东西   总是希望在获取此文档时回来。 翻转   这方面的一面是你不想在文档中嵌入东西   你不想再回来了。

如果您将我执行的活动嵌入到文档中,那么它将非常有用   首先是因为我的所有活动都在那里并且只有一次阅读   你可以找回你想给我看的一切:“你最近   点击这里,这是你的最后两条评论“但会发生什么   六个月过去了,我不关心我做了很长时间的事情   除非我特意去,否则你不想向我展示它们   寻找一些旧的活动?

首先,你最终将返回越来越大的文件和关怀   关于它的越来越小的部分。 但你可以使用投影   只返回一些数组,真正的痛苦就在于文档上   磁盘将变得更大,即使你只是,它仍将被读取   将部分返回给最终用户,但是因为我的活动是   只要我活跃就不会停止,文件将继续   成长和成长。

最明显的问题是最终你会达到16MB   文件限制,但这根本不是你应该关心的   关于。 不断增长的文件将越来越高   每次必须重新定位在磁盘上,即使你采取的成本   你的写作会减少碎片影响的步骤   整体上不必要地长,影响你的整体表现   整个申请。

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

我不希望这会吓到你使用数组时它们是好的   适合数据模型 - 它们是文档的强大功能   数据库数据模型,但与所有强大的工具一样,需要使用它   在适当的情况下,应小心使用。

efkan answered 2019-07-15T23:48:56Z
12 votes

基本上,创建一个变量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

Wayne Chiu answered 2019-07-15T23:49:30Z
9 votes

我认为这是由SO上的多个帖子在其他地方处理的。

一些:

  • MongoDB关系:嵌入还是引用?
  • 我应该如何在MongoDB中实现这个模式?
  • MongoDB架构设计 - 许多小文档或更少的大型文档?

最重要的是,这里没有单一的答案,只有一套相当复杂的权衡。

Gates VP answered 2019-07-15T23:50:17Z
translate from https://stackoverflow.com:/questions/15208711/mongoose-subdocuments-vs-nested-schema