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

Mongo trova e aggiorna in blocco il campo dei documenti corrispondenti in un'unica query?

Per migliorare le prestazioni, sfrutta l'utilizzo di un Bulk() API per aggiornare la raccolta in modo efficiente in blocco poiché invierai le operazioni al server in batch (ad esempio, ad esempio, una dimensione batch di 500). Ciò ti offre prestazioni molto migliori poiché non invierai tutte le richieste al server ma solo una volta ogni 500 richieste, rendendo così i tuoi aggiornamenti più efficienti e veloci.

Di seguito viene illustrato questo approccio, il primo esempio utilizza Bulk() API disponibile nelle versioni MongoDB>=2.6 e <3.2. Aggiorna tutti i documenti corrispondenti nella raccolta da un determinato array incrementando 1 nel campo mostrato. Presuppone che l'array di immagini abbia la struttura

var images = [
    { "_id": 1, "name": "img_1.png" },
    { "_id": 2, "name": "img_2.png" }
    { "_id": 3, "name": "img_3.png" },
    ...
    { "_id": n, "name": "img_n.png" }
]

Versioni MongoDB>=2.6 e <3.2 :

var bulk = db.images.initializeUnorderedBulkOp(),
    counter = 0;

images.forEach(function (doc) {    
    bulk.find({ "_id": doc._id }).updateOne({ 
        "$inc": { "shown": 1 }
    });

    counter++;
    if (counter % 500 === 0) {
        // Execute per 500 operations
        bulk.execute(); 
        // re-initialize every 500 update statements
        bulk = db.images.initializeUnorderedBulkOp();
    }
})
// Clean up remaining queue
if (counter % 500 !== 0) { bulk.execute(); }

Il prossimo esempio si applica al nuovo MongoDB versione 3.2 che da allora ha deprecato il Bulk() API e fornito un set più recente di API utilizzando bulkWrite() .

MongoDB versione 3.2 e successive :

var ops = [];
images.forEach(function(doc) {
    ops.push({
        "updateOne": {
            "filter": { "_id": doc._id },
            "update": {
                "$inc": { "shown": 1 }
            }
        }
    });

    if (ops.length === 500 ) {
        db.images.bulkWrite(ops);
        ops = [];
    }
})

if (ops.length > 0)  
    db.images.bulkWrite(ops);