【问题标题】:What are the performance implications of updating multiple fields using positional operator in MongoDB?在 MongoDB 中使用位置运算符更新多个字段对性能有何影响?
【发布时间】:2017-02-20 20:29:12
【问题描述】:

我在 MongoDB 中使用以下格式存储文档:

{  
    "id" : "123",  
    "tenure" : "360",  
    "details" : [  
        {  
            "trancheID" : "8087ed47-6e94-4733-ab0d-379ad420fbe2",  
            "amount" : "26000",  
            "status" : 2  
        },  
        {  
            "trancheID" : "096856fc-dac4-4dc9-af36-3764ffb9ab3b",  
            "amount" : "26000",  
            "status" : 2  
        },  
        {  
            "trancheID" : "45752678-04e6-490c-9836-d6c4a361e1d0",  
            "amount" : "26000",  
            "status" : 1  
        }  
    ]  
}

更新文档中的特定字段时,使用位置运算符$ 访问字段时设置新值的正确方法是什么?

在本例中,我想更新第三个元素的amountstatus,即查找条件为

{ "details.trancheID" : "45752678-04e6-490c-9836-d6c4a361e1d0" }

要更新字段,我有两种方法:

  1. 在客户端(java应用程序)构造新对象并在整个对象上使用$set

    { "$set" : { "details.$" : { // 这里是完整的对象 } }

因此,位置运算符将选择第一个匹配元素(使用trancheID 上的条件)并设置更新的对象。在这种方法中,我必须将整个对象(其大小可以达到 2KB)从应用程序发送到 MongoDB。

  1. 只设置查询中需要更新的字段,

    { "$set" : { "details.$.amount" : 50000", "details.$.status" : 3 } }

在这种情况下,位置运算符必须执行两次。我担心的是,如果使用位置运算符设置多个字段,这是否会导致任何性能损失?在这里,只有两个字段正在更新。但它最多可以有 5-6 个字段,details 数组中的元素数量可能很多(在某些情况下为 50 个)。

目前,trancheID 字段不是索引字段,但我正在考虑将其作为稀疏索引。假设它是一个索引字段,哪种方法会好?

另外,如果您可以向我指出一些可以阅读和理解 MongoDB 内部工作原理的资源(例如位置运算符在内部的工作方式),那将非常有帮助。谢谢!

我正在使用 MongoDB 3.0。

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    我担心的是,如果使用位置运算符设置多个字段,这是否会导致任何性能损失?

    没有性能损失。一旦找到匹配的元素,MongoDB 将 '$' 映射到该元素的数组下标。因此,在您的情况下,建议使用第二种方式,因为它可以节省通过网络传输整个元素的成本两次。而且,它更直接。

    与往常一样,我建议您使用生产数据集测试两种方式,看看性能有何不同。事实上,除非您的测试证明差异显着,否则我认为您不必担心这两种方式之间的性能差异。

    另外,如果您可以向我指出一些可以阅读和理解 MongoDB 内部工作原理的资源(例如位置运算符在内部的工作方式),那将非常有帮助。谢谢!

    MongoDB 是一个开源项目。在github,您将找到 MongoDB 服务器的源代码以及许多工具。至于 '$set' 和位置运算符,您可能需要查看 R3.2.10 源代码的 UpdateDriver::updateModifierSet::prepareModifierSet::apply

    我正在使用 MongoDB 3.0。

    请注意,当前的稳定版本是 3.2。而且,3.4 即将推出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-21
      • 1970-01-01
      • 1970-01-01
      • 2019-09-14
      • 1970-01-01
      • 1970-01-01
      • 2020-11-04
      相关资源
      最近更新 更多