Mongoose 子文档与嵌套模式

我很好奇使用子文档和在主模式中使用更深层次文档的利弊:

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


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

或者

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

我目前在任何地方都使用 subdocs,但我主要想知道我可能会遇到的性能或查询问题。

120818 次浏览

我认为这是处理其他地方的多个职位上所以。

只有几个:

最关键的是,这里没有单一的答案,只有一组相当复杂的权衡。

根据 那些文件的数据,完全一样。 但是,使用 Schema 也会添加一个 _id字段(只要您没有禁用该字段) ,并且可能会使用一些更多的资源来跟踪子文档。

替代声明语法

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

如果您的模式在模型的各个部分都被重用,那么为子文档定义单独的模式可能会很有用,这样您就不必复制自己了。

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

我希望这对寻找解决方案或最佳实践的人有所帮助。

原文发表于 http://askasya.com/post/largeembeddedarrays。 你可以访问她的 stackoverflow 个人 https://stackoverflow.com/users/431012/asya-kamsky ,地址是 < a href = “ https://stackoverflow. com/users/431012/asya-kamsky”>

首先,我们必须考虑为什么我们要这样做 通常情况下,我会建议人们嵌入他们 总是想回来时,他们取得这个文件。翻转 另一方面是你不想在文档中嵌入东西 你不想回到过去。

如果您将我执行的活动嵌入到文档中,它将在 首先,因为我所有的活动都在那里,只需一次阅读 你可以拿回所有你想给我看的东西“你最近” 点击这里,这里是你的最后两个评论”,但会发生什么 六个月过去了,我不在乎我做了很长时间的事情 你不想给我看,除非我特意去 寻找一些旧的活动?

首先,您最终将返回越来越大的文档和关心 但是你可以用投影来 只返回一些数组,真正的痛苦在于文档上 磁盘会变大,即使你只是 将它的一部分返回给最终用户,但由于我的活动是 只要我还活着,文件就不会停止 越来越大。

最明显的问题是,最终您将达到16MB 文件限制,但这根本不是你应该关心的 一个不断增长的文档会产生越来越多的问题 每次需要重新定位到磁盘上的时候都要花费一定的成本,即使你 步骤,以减轻碎片的影响,您的写将 不必要的长时间,影响你的整体表现 整个应用程序。

还有一件事,你可以做,这将完全杀死你的 应用程序的性能,这是索引这不断增加 这意味着文档每次使用 此数组被重新定位,即需要的索引项的数量 中的索引值数目成正比 数组越大,这个数字就越大 是。

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

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

这两者之间有一些区别:

  • 使用嵌套模式有助于验证。

  • 嵌套架构可以在其他架构中重用。

  • 嵌套模式将’_ id’字段添加到子文档,除非使用“ _ id: false”