我使用以下格式将文档存储在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
}
]
}
更新文档中的特定字段时,使用位置运算符$
访问字段时设置新值的正确方法是什么?
在此示例中,我想更新第三个元素的amount
和status
,即查找条件将
{“details.trancheID”:“45752678-04e6-490c-9836-d6c4a361e1d0”}
要更新字段,我有两种方法:
$set
,
{“$ set”:{“details。$”:{//此处为完整对象}}
因此,位置运算符将选择第一个匹配元素(使用trancheID
上的条件)并设置更新的对象。在这种方法中,我必须从应用程序将整个对象(其大小可以高达2KB)发送到MongoDB。
{“$ set”:{“details。$。amount”:50000“,”details。$。status“:3}}
在这种情况下,位置操作员必须采取行动两次。我担心的是,如果使用位置运算符设置了多个字段,是否会导致性能下降?这里只更新了两个字段。但它可以达到5-6个字段,details
数组中的元素数量可以很多(在某些情况下为50)。
现在,字段trancheID
不是索引字段,但我想将其作为稀疏索引。假设它是一个索引字段,哪种方法会好?
另外,如果你能指出一些资源,我可以阅读和理解MongoDB的内部工作方式(比如位置操作员如何在内部工作),那将非常有帮助。谢谢!
我正在使用MongoDB 3.0。
答案 0 :(得分:1)
我担心的是,如果使用位置运算符设置了多个字段,是否会导致性能下降?
没有性能损失。找到匹配元素后,MongoDB会映射“' $'到该元素的数组下标。因此,在您的情况下,建议使用第二种方法,因为它可以节省两次通过网络传输整个元素的成本。而且,它更直接。
与往常一样,我建议您使用生产数据集测试两种方式,以了解性能的差异。事实上,除非你的测试证明差异很大,否则我认为你不应该担心这两种方式之间的性能差异。
另外,如果你能指出一些资源,我可以阅读和理解MongoDB的内部工作方式(比如位置操作员如何在内部工作),那将非常有帮助。谢谢!
MongoDB是一个开源项目。在github上,您将找到MongoDB服务器的源代码以及许多工具。至于' $ set'和位置运算符,您可能需要查看R3.2.10源代码的UpdateDriver::update,ModifierSet::prepare和ModifierSet::apply。
我正在使用MongoDB 3.0。
请注意,目前的稳定版本是3.2。而且,3.4即将推出。