I betragtning af din kommentar ser du ud til at være på rette vej. Som du ved, er positionelle $
operator er blot en "værdi"-beholder, der har indekset af det første array-element, der matches i din forespørgsel.
Du "kunne" brug det, hvis du var absolut sikker på, at dine to arrays altid indeholdt det samme antal elementer, og at disse tilsvarende poster hele tiden var på samme position.
Så ja, for at være sikker, brug $elemMatch med to opdateringshandlinger som sådan
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'
}
})
Den eneste reelle overvejelse her er på grund af de to opdateringer, det er muligt at en læst af dokumentet kunne forekomme mellem disse opdateringer og dine _searchData
og _children
dokumenter ville ikke have det samme tilsvarende poster i adresserR
arrays.
Det samme gælder med replikering, da begge operationer skal genafspilles ved de sekundære knudepunkter.
Hvad der ville være en god funktion, ville være at kunne bruge $elemMatch i opdateringen del af din forespørgsel. På den måde ville du spørge efter elementets placering på den side. Men dette eksisterer ikke endnu . Men fra 2,6 og opefter kan gør noget som dette:
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"
}
}
}
]
})
Det er dækket på manualsiden under Masseopdatering .