MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Aggiorna tutti gli elementi in un array in mongodb

Come accennato, il problema principale qui riguarda gli aggiornamenti su più elementi con l'operatore posizionale come registrato in questo numero di vecchia data:http://jira.mongodb.org/browse/SERVER-1243

Il caso di base quindi è che nessuna singola esecuzione può farlo, quindi per elaborare più elementi dell'array è necessario un metodo per determinare quanti elementi sono necessari per aggiornare ed elaborare un'istruzione di aggiornamento per ciascun elemento.

Un approccio semplificato a questo è generalmente l'utilizzo di Operazioni in blocco per elaborare quelle che finiscono per essere operazioni di aggiornamento "multiple" come una singola richiesta e risposta al server:

var bulk = db.collection.initializeOrderedBulkOp(),
    count = 0;

db.collection.find({ "name": "John Doe", "adds.status": "PENDING" }).forEach(function(doc) { 
    doc.adds.filter(function(add){ return add.status = "PENDING" }).forEach(function(add) {
        bulk.find({ "_id": doc._id, "adds.status": "PENDING" }).updateOne({
            "$set": { "adds.$.status": "APPROVED" }
        });
        count++;

        // Execute once in 1000 statements created and re-init
        if ( count % 1000 == 0 ) {
            bulk.execute();
            bulk = db.collection.initializeOrderedBulkOp();
        }
    });
});

// Execute any pending operations
if ( count % 1000 != 0 )
    bulk.execute();

Se i tuoi documenti aggiornati sono piuttosto piccoli, o addirittura solo un singolo documento, puoi rinunciare al count controlla e aggiungi semplicemente tutti gli aggiornamenti in blocco all'interno dei loop richiesti ed esegui semplicemente una volta alla fine di tutti i loop.

Una spiegazione più lunga e alternative sono disponibili su Come aggiornare più elementi di array , ma tutti si riducono a approcci diversi per abbinare l'elemento per aggiornare ed elaborare un posizionale $ aggiorna più volte, per ogni documento abbinato o fino a quando non ci sono più documenti modificati restituiti.