MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

$ posicional trabalhando em diferentes partes do mesmo documento?


Considerando seu comentário, parece que está no caminho certo. Como você sabe, o posicional $ operador é apenas um contêiner de "valor", que tem o índice do primeiro elemento da matriz correspondido em sua consulta.

Você "poderia" use isso se você estivesse absolutamente certifique-se de que suas duas matrizes sempre continham o mesmo número de elementos e que essas entradas correspondentes estavam sempre na mesma posição.

Então, sim, para estar seguro, use $elemMatch com dois operações de atualização assim
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'
  }
})

A única consideração real aqui é por causa das duas atualizações, é possível que um leia do documento poderia ocorrem entre essas atualizações e seus _searchData e _children documentos não teriam o mesmo correspondente entradas no addressesR matrizes.

A mesma coisa se aplica à replicação, pois ambas as operações precisam ser repetidas pelos nós secundários.

O que seria um bom recurso seria poder usar $elemMatch na atualização parte da sua consulta. Dessa forma, você estaria consultando a posição do elemento desse lado. Mas isso não existe ainda . Mas de 2.6 para cima você pode faça algo assim:
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"
                }
            }
        }

    ]
})

Isso é abordado na página do manual em Atualização em massa .