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

Aggrega e aggiorna MongoDB

Per prestazioni migliori, soprattutto quando si tratta di raccolte di grandi dimensioni, approfitta dell'utilizzo di Bulk() API per aggiornamenti in blocco poiché invierai le operazioni al server in batch (ad esempio, diciamo una dimensione batch di 1000) che ti offre prestazioni molto migliori poiché non invierai tutte le richieste al server (come stai attualmente fare con la dichiarazione di aggiornamento all'interno di forEach() loop) ma solo una volta ogni 1000 richieste, rendendo così i tuoi aggiornamenti più efficienti e veloci di quanto non lo siano attualmente.

Gli esempi seguenti dimostrano questo approccio, il primo utilizza il Bulk() API disponibile nelle versioni MongoDB >= 2.6 and < 3.2 . Aggiorna tutti i documenti nei clients raccolta modificando il nb_orders_1year campi con valori dai risultati dell'aggregazione.

Dal momento che il aggregate() il metodo restituisce un cursor , È possibile utilizzare forEach() metodo per iterarlo e accedere a ciascun documento, impostando così le operazioni di aggiornamento in blocco in batch da inviare poi attraverso il server in modo efficiente con l'API:

var bulk = db.clients.initializeUnorderedBulkOp(),
    pipeline = [
        {
            "$match": { "date_order": { "$gt": v_date1year } }
        },
        {
            "$group": {
                "_id": "$id_client", 
                "count": { "$sum" : 1 }
            }
        },
        { "$out": "tmp_indicators" }        
    ],
    counter = 0;

db.orders.aggregate(pipeline);  
db.tmp_indicators.find().forEach(function (doc) {       
    bulk.find({ "_id": doc._id }).updateOne({ 
        "$set": { "nb_orders_1year": doc.count }
    });

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

Il prossimo esempio si applica alla nuova versione di MongoDB 3.2 che da allora ha deprecato il Bulk API e ha fornito una serie più recente di API utilizzando bulkWrite() .

Utilizza lo stesso cursore di cui sopra ma invece di iterare il risultato, crea l'array con le operazioni di massa utilizzando il suo map() metodo:

 var pipeline = [
        {
            "$match": { "date_order": { "$gt": v_date1year } }
        },
        {
            "$group": {
                "_id": "$id_client", 
                "count": { "$sum" : 1 }
            }
        },
        { "$out": "tmp_indicators" }        
    ];
db.orders.aggregate(pipeline);
var bulkOps = db.tmp_indicators.find().map(function (doc) { 
        return { 
            "updateOne": { 
                "filter": { "_id": doc._id } ,              
                "update": { "$set": { "nb_orders_1year": doc.count } } 
            }         
        };
    });

db.clients.bulkWrite(bulkOps, { "ordered": true });