Xem xét bạn nhận xét bạn có vẻ đang đi đúng hướng. Như bạn đã biết, vị trí $
toán tử chỉ là một vùng chứa "giá trị", có chỉ mục của phần tử mảng đầu tiên được so khớp trong truy vấn của bạn.
Bạn "có thể" sử dụng điều đó nếu bạn hoàn toàn chắc chắn rằng hai mảng của bạn luôn luôn chứa cùng một số phần tử và các mục nhập tương ứng này luôn ở cùng một vị trí.
Vì vậy, để an toàn, hãy sử dụng $ elemMatch với hai cập nhật các hoạt động như vậy
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'
}
})
Sự cân nhắc thực sự duy nhất ở đây là do hai bản cập nhật này có thể rằng một đọc của tài liệu could xảy ra giữa các bản cập nhật đó và _searchData
của bạn và _children
các tài liệu sẽ không giống nhau tương ứng các mục nhập trong addressR
mảng.
Điều tương tự cũng áp dụng với sao chép, vì cả hai hoạt động đều phải được phát lại bởi các nút thế tục.
Một tính năng thú vị sẽ là gì, có thể sử dụng $ elemMatch trong bản cập nhật một phần của truy vấn của bạn. Theo cách đó, bạn sẽ truy vấn vị trí của phần tử ở phía đó. Nhưng điều này không tồn tại chưa . Nhưng từ 2,6 trở lên, bạn có thể làm điều gì đó như thế này:
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"
}
}
}
]
})
Điều đó được đề cập trong trang hướng dẫn trong Cập nhật hàng loạt .