在MongoDB中使用位置运算符更新多个字段有什么性能影响?

时间:2016-10-12 06:24:29

标签: mongodb

我使用以下格式将文档存储在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。$”:{//此处为完整对象}}

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

    1. 仅设置查询中必须更新的字段,
        

      {“$ set”:{“details。$。amount”:50000“,”details。$。status“:3}}

    2. 在这种情况下,位置操作员必须采取行动两次。我担心的是,如果使用位置运算符设置了多个字段,是否会导致性能下降?这里只更新了两个字段。但它可以达到5-6个字段,details数组中的元素数量可以很多(在某些情况下为50)。

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

      另外,如果你能指出一些资源,我可以阅读和理解MongoDB的内部工作方式(比如位置操作员如何在内部工作),那将非常有帮助。谢谢!

      我正在使用MongoDB 3.0。

1 个答案:

答案 0 :(得分:1)

  

我担心的是,如果使用位置运算符设置了多个字段,是否会导致性能下降?

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

与往常一样,我建议您使用生产数据集测试两种方式,以了解性能的差异。事实上,除非你的测试证明差异很大,否则我认为你不应该担心这两种方式之间的性能差异。

  

另外,如果你能指出一些资源,我可以阅读和理解MongoDB的内部工作方式(比如位置操作员如何在内部工作),那将非常有帮助。谢谢!

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

  

我正在使用MongoDB 3.0。

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