gpt4 book ai didi

mongodb - 更新 Mongodb 中的嵌入文档 : Performance issue?

转载 作者:可可西里 更新时间:2023-11-01 09:39:31 25 4
gpt4 key购买 nike

我是 Mongodb 的新手,听说 Mongodb 非常适合海量读写操作。嵌入式文档是实现这一目标的功能之一。但我不确定这是否也是性能问题的原因。书籍文档示例:

{
"_id": 1,
"Authors": [
{
"Email": "email",
"Name": "name"
}
],
"Title": "title",
...
}

如果一个作者有几千本书,他的邮箱需要更新,我需要写一些查询可以

  1. 搜索所有书籍文档,挑出几千个有这个作者的
  2. 在这些书籍文档中更新作者的电子邮件字段

这些操作看起来效率不高。但这种更新无处不在,相信开发者已经考虑到了这一点。那么,我哪里做错了?

最佳答案

您当前的嵌入式模式设计有其优点,其中之一就是数据局部性。由于 MongoDB 在磁盘上连续存储数据,将您需要的所有数据放在一个文档中可确保旋转磁盘花费更少的时间来寻找磁盘上的特定位置。

如果您的应用程序经常访问 books 信息以及 Authors 数据,那么您几乎肯定会希望采用嵌入式路线。嵌入式文档的另一个优点是写入数据的原子性和隔离性。

为了说明这一点,假设您希望一位作者的所有书籍都更新他的电子邮件字段,这可以通过一个(原子)操作完成,这不是 MongoDB 的性能问题:

db.books.updateMany(
{ "Authors.name": "foo" },
{
"$set": { "Authors.$.email": "new@email.com" }
}
);

或早期的 MongoDB 版本:

db.books.update(
{ "Authors.name": "foo" },
{
"$set": { "Authors.$.email": "new@email.com" }
},
{ "multi": true }
)

在上面,您使用了 positional $ operator它通过识别数组中要更新的元素而不显式指定数组中元素的位置来促进对包含嵌入式文档的数组的更新。与 dot notation 一起使用在 $ 运算符上。

有关 MongoDB 中数据建模的更多详细信息,请阅读文档 Data Modeling Introduction , 特别是 Model One-to-Many Relationships with Embedded Documents .


您可以考虑的另一个设计选项是引用遵循规范化模式的文档。例如:

// db.books schema
{
"_id": 3
"authors": [1, 2, 3] // <-- array of references to the author collection
"title": "foo"
}

// db.authors schema
/*
1
*/
{
"_id": 1,
"name": "foo",
"surname": "bar",
"address": "xxx",
"email": "foo@mail.com"
}
/*
2
*/
{
"_id": 2,
"name": "abc",
"surname": "def",
"address": "xyz",
"email": "abc@mail.com"
}
/*
3
*/
{
"_id": 3,
"name": "alice",
"surname": "bob",
"address": "xyz",
"email": "alice@mail.com"
}

当您拥有非常不可预测的一对多关系时,上述使用文档引用方法的规范化模式也有优势。如果每个给定的书实体有成百上千个作者文档,那么嵌入在空间限制方面会遇到很多挫折,因为文档越大,它使用的 RAM 就越多,而 MongoDB 文档的硬大小限制为 16MB。

对于规范化模式的查询,可以考虑使用聚合框架的 $lookup 运算符,它对同一数据库中的 authors 集合执行左外连接,以从 books 集合中过滤文档进行处理。


因此,我相信您当前的模式是比创建单独的 authors 集合更好的方法,因为单独的集合需要更多的工作,即查找一本书 + 它的作者是两个查询,需要额外的工作,而上述模式嵌入文档简单快捷(单次搜索)。插入和更新没有太大区别。因此,如果您需要选择单个文档、需要对查询进行更多控制或拥有大量文档,则单独的集合是很好的选择。当您想要整个文档时,嵌入式文档也很好,带有 $slice 的文档 嵌入的作者,或者根本没有作者

一般的经验法则是,如果您的应用程序的查询模式众所周知并且数据往往只能以一种方式访问​​,那么嵌入式方法会很有效。如果您的应用程序以多种方式查询数据,或者您无法预测数据查询模式,则更规范化的文档引用模型将适用于这种情况。

引用:

MongoDB Applied Design Patterns: Practical Use Cases with the Leading NoSQL Database By Rick Copeland

关于mongodb - 更新 Mongodb 中的嵌入文档 : Performance issue?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40157403/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com