当前位置: 首页 > 知识库问答 >
问题:

更新MongoDB中的嵌入式文档:性能问题?

颛孙高义
2023-03-14
{
    "_id": 1,
    "Authors": [
        {
            "Email": "email",
            "Name": "name"
        }
    ],
    "Title": "title",
    ...
}
    null

这些操作似乎效率不高。但是这种类型的更新是无处不在的,我相信开发者已经考虑到了这一点。那么,我哪里搞错了?

共有1个答案

王豪
2023-03-14

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

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

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

db.books.updateMany(
    { "Authors.name": "foo" },
    {
        "$set": { "Authors.$.email": "new@email.com" }
    }
);
db.books.update(
    { "Authors.name": "foo" },
    {
        "$set": { "Authors.$.email": "new@email.com" }
    },
    { "multi": true }
)
// 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"
}

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

因此,我相信您当前的模式比创建一个单独的作者集合更好,因为单独的集合需要更多的工作,即查找一本书+它的作者需要两个查询,需要额外的工作,而上面的模式嵌入的文档很容易而且快速(单次查找)。插入和更新没有大的区别。因此,如果您需要选择单独的文档、需要对查询进行更多的控制或拥有大量的文档,那么单独的集合是很好的。当您需要整个文档、包含嵌入的authors$slice或根本不包含authors的文档时,嵌入文档也很好。

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

 类似资料:
  • 我想在具有指定 URL 的相应文档中将嵌套的“已爬行”更新为 True。 我对mongodb相当陌生,我似乎无法弄清楚这一点,非常感谢任何帮助。

  • 问题内容: 我浏览了猫鼬API,以及关于SO和google小组的许多问题,但仍然无法弄清更新嵌入式文档。 我正在尝试使用args的内容更新此特定的userListings对象。 以下是架构: 此发现也不起作用,这可能是第一个问题: 返回: 那应该等同于此mongo客户呼叫: 运行: 问题答案: 当您已有用户时,您可以执行以下操作: 如在这里找到:http : //mongoosejs.com/do

  • 我正在尝试使用Spring Data mongodb更新mongodb中嵌入文档中的数组字段。 我想在mongodb集合中更新/插入的文档结构如下所示。 可以有更多这样的文档基于每个类型的部门,如“销售”,“市场营销”等。 即使这样做有效,我也不确定在Spring Data MongoDB中实现相同的功能是否有类似的支持。 另外,我的另一个查询是,如果我想为多个部门添加/更新员工,比如“Accou

  • 我需要更新Mongo DB中另一个文档内的数组中的一个文档

  • 主要内容:update() 方法,save() 方法在 MongoDB 中,可以使用 update() 和 save() 方法来更新集合中的文档。其中 update() 方法可以更新现有文档中的值,而 save() 方法则可以使用传入文档来替换已有文档。 update() 方法 update() 方法用于更新现有文档中的值,其语法格式如下: db.collection_name.update(     <query>,     <update>,

  • 我有一个深度嵌套的文档结构,如下所示: 我正在尝试更新集合以插入新配置,如下所示: 我正在mongo(Python)中尝试类似的内容: 但是,我得到了“如果没有包含数组的相应查询字段,则无法应用位置运算符”错误。在mongo这样做的正确方式是什么?这是mongo v2。4.1.