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

Mongo encontra e atualiza o campo de documentos correspondentes em uma única consulta?


Para melhorar o desempenho, aproveite o uso de um Bulk() API para atualizar a coleção de forma eficiente em massa, pois você enviará as operações para o servidor em lotes (por exemplo, digamos um tamanho de lote de 500). Isso oferece um desempenho muito melhor, pois você não enviará todas as solicitações ao servidor, mas apenas uma vez a cada 500 solicitações, tornando suas atualizações mais eficientes e rápidas.

O seguinte demonstra essa abordagem, o primeiro exemplo usa o método Bulk() API disponível nas versões do MongoDB>=2.6 e <3.2. Ele atualiza todos os documentos correspondentes na coleção de um determinado array, incrementando 1 no campo mostrado. Ele assume que o array de imagens tem a estrutura
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" }
]

Versões do 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(); }

O próximo exemplo se aplica ao novo MongoDB versão 3.2, que desde então desativou o Bulk() API e forneceu um novo conjunto de APIs usando bulkWrite() .

MongoDB versão 3.2 e 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);