Mongodb 位置$处理同一文档的不同部分?

Mongodb 位置$处理同一文档的不同部分?,mongodb,mongodb-query,Mongodb,Mongodb Query,我有以下记录: r = { "_children" : { "addressesR" : [ { "street" : "Bitton", "city" : "Perth", "id" : ObjectId("5317c149f45dfdb114deec41") }, { "

我有以下记录:

r = {
    "_children" : {
        "addressesR" : [
            {
                "street" : "Bitton",
                "city" : "Perth",
                "id" : ObjectId("5317c149f45dfdb114deec41")
            },
            {
                "id" : ObjectId("5317c149f45dfdb114deec42"),
                "street" : "Ivermey",
                "city" : "Perth",
        ],
    },
    "_searchData" : {
        "addressesR" : [
            {
                "street" : "BITTON",
                "city" : "PERTH",
                "id" : ObjectId("5317c149f45dfdb114deec41")
            },
            {
                "id" : ObjectId("5317c149f45dfdb114deec42"),
                "street" : "IVERMEY",
                "city" : "PERTH",
            }
        ],
    },
}
只要保存它:

db.p.save( r );
该记录有两个子文档:一个子文档有子文档列表,另一个子文档有相同的子文档列表,但为大写(用于搜索)

当我更新时,我希望能够同时更新两者。现在,这是可行的:

db.p.update( { '$and': [ 
  { '_searchData.addressesR.street': 'BITTON' } ] },
  { '$set': {
    '_searchData.addressesR.$.street':'BITTON CHANGED' ,
    '_children.addressesR.$.street': 'Bitton CHANGED'
  }
})
$
运算符是位置运算符。因此,如果位置匹配,它将正常工作。然而,如果由于任何原因职位不匹配,我怀疑我将走向灾难

现在,考虑到我总是在同一个mongoDb查询中同时$push到这两个数组,同时从它们中$pull,我应该同意吗

另外,在db正在进行复制的环境中,这会起作用吗(请参阅:位置将始终保持不变)


(注意:这是一个自动机制的最终结果,该机制在一条记录中获取子记录。)

考虑到您的评论,您似乎走在了正确的轨道上。正如您所知,操作符只是一个“值”容器,它的索引与查询中的第一个数组元素相匹配

如果您是绝对的话,您“可以”使用它,确保您的两个数组始终包含相同数量的元素,并且这些对应的条目始终处于相同的位置

因此,是的,为了安全起见,请与两个类似的更新操作一起使用

db.p.update({'$and':[
{{u searchData.addressesR':{$elemMatch:{'street':'BITTON'}}},
{'$set':{
“_searchData.addressesR.$.street”:“BITTON已更改”,
}
})
db.p.update({'$and':[
{'u children.addressesR':{$elemMatch:{'street':'Bitton'}}},
{'$set':{
“_children.addressesR.$.street”:“Bitton已更改”
}
})
这里唯一需要考虑的是,由于这两次更新,文档的读取可能发生在这些更新之间,并且您的
\u searchData
\u子文档在
addressesR
数组中不具有相同的对应条目

同样的事情也适用于复制,因为这两个操作都必须由secordary节点重放

一个很好的功能是能够在查询的更新部分使用$elemMatch。这样,您可以查询元素在那一侧的位置。但是这还不存在。但是从2.6开始,您可以执行如下操作:

db.runCommand({
“更新”:“p”,
“更新”:[
{ 
“q”:{{u children.addressesR':{$elemMatch:{‘street’:‘Bitton’},
“u”:{
“$set”:{
_children.addressesR.$.street:“Bitton已更改”
}
}
},
{ 
“q”:{u searchData.addressesR':{$elemMatch:{'street':'BITTON'},
“u”:{
“$set”:{
_searchData.addressesR.$.street:“BITTON已更改”
}
}
}
]
})

这在下的手册页中有介绍。

我想也许我应该运行两个不同的更新,每个更新都使用
$elemMatch
来匹配阵列的子集…也许这比假设阵列永远不会在位置上失去同步更安全?这是一种方式。我只能给你一些关于这方面的说明和未来e作为回应的审议。