sql >> Databasteknik >  >> NoSQL >> MongoDB

Aggregera och uppdatera MongoDB

För förbättrad prestanda, särskilt när du har att göra med stora samlingar, dra fördel av att använda Bulk() API för massuppdateringar eftersom du kommer att skicka operationerna till servern i omgångar (till exempel en batchstorlek på 1000) vilket ger dig mycket bättre prestanda eftersom du inte kommer att skicka varje begäran till servern (som du för närvarande gör gör med uppdateringssatsen i forEach() loop) men bara en gång av 1000 förfrågningar, vilket gör dina uppdateringar mer effektiva och snabbare än för närvarande.

Följande exempel visar detta tillvägagångssätt, det första använder Bulk() API tillgängligt i MongoDB-versionerna >= 2.6 and < 3.2 . Den uppdaterar alla dokument i clients insamling genom att ändra nb_orders_1year fält med värden från aggregeringsresultaten.

Sedan aggregate() metod returnerar en cursor , Du kan använda aggregeringsutdatasamlingens forEach() metod för att iterera det och komma åt varje dokument och därmed ställa in massuppdateringsoperationerna i omgångar för att sedan skicka över servern effektivt med API:et:

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

Nästa exempel gäller den nya MongoDB-versionen 3.2 som sedan fasade ut Bulk API och tillhandahöll en nyare uppsättning apis med bulkWrite() .

Den använder samma markör som ovan men istället för att iterera resultatet, skapa arrayen med bulkoperationerna genom att använda dess map() metod:

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



  1. Använder StackExchange.Redis-klient med Redis-kluster

  2. python flask hur man skickar en dynamisk parameter till en dekoratör

  3. Hur man lagrar listelement i Redis cache

  4. Hur mäts $maxDistance i MongoDB?