sql >> Base de Datos >  >> NoSQL >> MongoDB

¿Mongo busca masivamente y actualiza el campo de documentos coincidentes en una sola consulta?

Para mejorar el rendimiento, aproveche el uso de Bulk() API para actualizar la colección de manera eficiente en masa, ya que enviará las operaciones al servidor en lotes (por ejemplo, digamos un tamaño de lote de 500). Esto le brinda un rendimiento mucho mejor, ya que no enviará todas las solicitudes al servidor, sino solo una de cada 500 solicitudes, lo que hará que sus actualizaciones sean más eficientes y rápidas.

Lo siguiente demuestra este enfoque, el primer ejemplo usa Bulk() API disponible en las versiones de MongoDB>=2.6 y <3.2. Actualiza todos los documentos coincidentes en la colección de una matriz dada incrementando 1 al campo mostrado. Asume que la matriz de imágenes tiene la estructura

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

Versiones de MongoDB>=2.6 y <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(); }

El siguiente ejemplo se aplica a la nueva versión 3.2 de MongoDB, que desde entonces ha dejado en desuso Bulk() API y proporcionó un conjunto más nuevo de apis usando bulkWrite() .

MongoDB versión 3.2 y superior :

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