我有以下记录:
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查询中,我应该对此好吗?
此外,这是否会在db进行复制的环境中起作用(参见:位置总是一样)?
(注意:这是在一条记录中获取子记录的自动机制的最终结果。)
答案 0 :(得分:1)
考虑到你发表评论,你似乎走在了正确的轨道上。如您所知,positional $
运算符只是一个“值”容器,其中包含查询中匹配的第一个数组元素的索引。
你“可以”使用它,如果你绝对确定你的两个数组总是包含相同数量的元素并且这些条目始终处于相同的位置。
是的,为了安全起见,请将$elemMatch与两次更新操作一起使用
db.p.update( { '$and': [
{ '_searchData.addressesR': {$elemMatch: { 'street': 'BITTON' } } ] },
{ '$set': {
'_searchData.addressesR.$.street':'BITTON CHANGED' ,
}
})
db.p.update( { '$and': [
{ '_children.addressesR': {$elemMatch: { 'street': 'Bitton' } } ] },
{ '$set': {
'_children.addressesR.$.street': 'Bitton CHANGED'
}
})
这里唯一真正的考虑是因为可能这两个更新 并且您的_searchData
和_children
文档在addressesR
数组中没有相同的对应条目。
同样适用于复制,因为两个操作都必须由辅助节点重放。
什么是一个不错的功能,是能够在查询的更新部分中使用$ elemMatch。通过这种方式,您将查询该侧元素的位置。但这不存在尚未。但是从2.6以上你可以做这样的事情:
db.runCommand({
"update": "p",
"updates": [
{
"q": { '_children.addressesR': {$elemMatch: { 'street': 'Bitton' } },
"u": {
"$set": {
"_children.addressesR.$.street": "Bitton CHANGED"
}
}
},
{
"q": { '_searchData.addressesR': {$elemMatch: { 'street': 'BITTON' } },
"u": {
"$set": {
"_searchData.addressesR.$.street": "BITTON CHANGED"
}
}
}
]
})
Bulk Update下的手册页中介绍了这一点。