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

MongoDB atualiza todos os campos de erro de array

EDITAR


O detalhe que faltava na pergunta era que o campo obrigatório para atualização estava na verdade em um subdocumento . Isso muda consideravelmente a resposta:

Esta é uma restrição do que você pode possivelmente fazer com a atualização de elementos da matriz. E isso está claramente explicado na documentação . Principalmente neste parágrafo:

O negócio é o seguinte. Tentando atualizar todos dos elementos da matriz em uma única instrução como esta não trabalhar. Para fazer isso, você deve fazer o seguinte.
db.warehouses.find({ "items.qty": { "$gt": 0 } }).forEach(function(doc) {
    doc.items.forEach(function(item) {
        item.qty = 0;
    });
    db.warehouses.update({ "_id": doc._id }, doc );
})

Que é basicamente a maneira de atualizar todas elemento de matriz.

O multi configuração em .update() significa em vários "documentos". Ele não pode ser aplicado a vários elementos de uma matriz. Então, atualmente, a melhor opção é substituir a coisa toda. Ou, neste caso, podemos substituir o todo documento, pois precisamos fazer isso de qualquer maneira.

Para real dados em massa, use db.eval() . Mas por favor leia a documentação primeiro:
db.eval(function() {
    db.warehouses.find({ "items.qty": { "$gt": 0 } }).forEach(function(doc) {
        doc.items.forEach(function(item) {
            item.qty = 0;
        });
        db.warehouses.update({ "_id": doc._id }, doc );
    });
})

Atualizando todos os elementos em uma matriz em todo coleta não é simples.

Original


Praticamente exatamente o que o erro diz. Para usar um operador posicional, você precisa corresponder algo primeiro. Como em:
db.warehouses.update(
    // query 
    {
        _id:ObjectId('5322f07e139cdd7e31178b78'),
        "items.qty": { "$gt": 0 }
    },    
    // update 
    {
        $set:{"items.$.qty":0}
    },    
    // options 
    {
        "multi" : true,  
        "upsert" : true  
    }
);

Então, onde a corresponde condição termina a posição dos itens que são menos que 0 então esse índice é passado para o operador posicional.

PS :Quando mudar é verdadeiro significa que atualiza a cada documento. Deixe false se você quer dizer apenas um . Qual é o padrão.