sql >> Databasteknik >  >> NoSQL >> MongoDB

Hur uppdaterar man ett stort antal dokument i MongoDB mest effektivt?

Om din MongoDB-server är 2.6 eller nyare skulle det vara bättre att använda skrivkommandon Bulk API som tillåter exekvering av bulk update operationer som helt enkelt är abstraktioner ovanpå servern för att göra det enkelt att bygga bulkoperationer. Dessa bulkoperationer kommer huvudsakligen i två smaker:

  • Beställda massoperationer . Dessa operationer utför alla operationer i ordning och fel vid det första skrivfelet.
  • Obeställda massoperationer . Dessa operationer utför alla operationer parallellt och aggregerar alla fel. Oordnade massoperationer garanterar inte utförandeordning.

Observera att för äldre servrar än 2.6 kommer API:et att nedkonvertera operationerna. Det är dock inte möjligt att nedkonvertera 100 %, så det kan finnas vissa kantfall där det inte kan rapportera rätt siffror korrekt.

För dina tre vanliga användningsfall kan du implementera Bulk API så här:

Fall 1. Ändra typ av värde på fastighet, utan att ändra värdet:

var MongoClient = require('mongodb').MongoClient;

MongoClient.connect("mongodb://localhost:27017/test", function(err, db) {
    // Handle error
    if(err) throw err;

    // Get the collection and bulk api artefacts
    var col = db.collection('users'),           
        bulk = col.initializeOrderedBulkOp(), // Initialize the Ordered Batch
        counter = 0;        

    // Case 1. Change type of value of property, without changing the value.        
    col.find({"timestamp": {"$exists": true, "$type": 2} }).each(function (err, doc) {

        var newTimestamp = parseInt(doc.timestamp);
        bulk.find({ "_id": doc._id }).updateOne({
            "$set": { "timestamp": newTimestamp }
        });

        counter++;

        if (counter % 1000 == 0 ) {
            bulk.execute(function(err, result) {  
                // re-initialise batch operation           
                bulk = col.initializeOrderedBulkOp();
            });
        }
    });

    if (counter % 1000 != 0 ){
        bulk.execute(function(err, result) {
            // do something with result
            db.close();
        }); 
    } 
});

Fall 2. Lägg till ny egendom baserat på värdet på befintlig egendom:

MongoClient.connect("mongodb://localhost:27017/test", function(err, db) {
    // Handle error
    if(err) throw err;

    // Get the collection and bulk api artefacts
    var col = db.collection('users'),           
        bulk = col.initializeOrderedBulkOp(), // Initialize the Ordered Batch
        counter = 0;        

    // Case 2. Add new property based on value of existing property.        
    col.find({"name": {"$exists": false } }).each(function (err, doc) {

        var fullName = doc.firstname + " " doc.lastname;
        bulk.find({ "_id": doc._id }).updateOne({
            "$set": { "name": fullName }
        });

        counter++;

        if (counter % 1000 == 0 ) {
            bulk.execute(function(err, result) {  
                // re-initialise batch operation           
                bulk = col.initializeOrderedBulkOp();
            });
        }
    });

    if (counter % 1000 != 0 ){
        bulk.execute(function(err, result) {
            // do something with result
            db.close();
        }); 
    } 
});

Fall 3. Lägg helt enkelt till för att ta bort egenskaper från dokument.

MongoClient.connect("mongodb://localhost:27017/test", function(err, db) {
    // Handle error
    if(err) throw err;

    // Get the collection and bulk api artefacts
    var col = db.collection('users'),           
        bulk = col.initializeOrderedBulkOp(), // Initialize the Ordered Batch
        counter = 0;        

    // Case 3. Simply adding removing properties from documents.    
    col.find({"street_no": {"$exists": true } }).each(function (err, doc) {

        bulk.find({ "_id": doc._id }).updateOne({
            "$set": { "no": doc.street_no },
            "$unset": { "street_no": "" }
        });

        counter++;

        if (counter % 1000 == 0 ) {
            bulk.execute(function(err, result) {  
                // re-initialise batch operation           
                bulk = col.initializeOrderedBulkOp();
            });
        }
    });

    if (counter % 1000 != 0 ){
        bulk.execute(function(err, result) {
            // do something with result
            db.close();
        }); 
    } 
});



  1. MongoDB:Är det möjligt att göra en skiftlägesokänslig fråga?

  2. Designa en applikation med Redis som datalager. Vad? Varför?

  3. Nodejs kan inte ansluta till mongodb på molnskalet

  4. 2 metoder för att spåra onlineanvändare med Redis. Vilken är snabbare?