MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Mongo recherche en masse et met à jour le champ des documents correspondants en une seule requête ?

Pour de meilleures performances, profitez de l'utilisation d'un Bulk() API pour mettre à jour efficacement la collection en masse car vous enverrez les opérations au serveur par lots (par exemple, disons une taille de lot de 500). Cela vous donne de bien meilleures performances puisque vous n'enverrez pas toutes les requêtes au serveur mais une seule requête sur 500, ce qui rendra vos mises à jour plus efficaces et plus rapides.

Ce qui suit illustre cette approche, le premier exemple utilise le Bulk() API disponible dans les versions MongoDB>=2.6 et <3.2. Il met à jour tous les documents correspondants dans la collection à partir d'un tableau donné en incrémentant 1 dans le champ affiché. Il suppose que le tableau d'images a la structure

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" }
]

Versions MongoDB>=2.6 et <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(); }

L'exemple suivant s'applique à la nouvelle version 3.2 de MongoDB qui a depuis déprécié le Bulk() API et a fourni un ensemble d'API plus récent à l'aide de bulkWrite() .

MongoDB version 3.2 et supérieure :

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);