MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Mongo-Massensuche und -aktualisierung des Felds für übereinstimmende Dokumente in einer einzigen Abfrage?

Nutzen Sie für eine verbesserte Leistung die Verwendung von Bulk() API zum effizienten Massenaktualisieren der Sammlung, da Sie die Vorgänge in Stapeln an den Server senden (z. B. eine Stapelgröße von 500). Dadurch erhalten Sie eine viel bessere Leistung, da Sie nicht jede Anfrage an den Server senden, sondern nur einmal alle 500 Anfragen, wodurch Ihre Aktualisierungen effizienter und schneller werden.

Im Folgenden wird dieser Ansatz demonstriert, das erste Beispiel verwendet Bulk() API verfügbar in MongoDB-Versionen>=2.6 und <3.2. Es aktualisiert alle übereinstimmenden Dokumente in der Sammlung aus einem bestimmten Array, indem es das angezeigte Feld um 1 erhöht. Es wird davon ausgegangen, dass das Array von Bildern die Struktur

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

MongoDB-Versionen>=2.6 und <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(); }

Das nächste Beispiel gilt für die neue MongoDB-Version 3.2, die seitdem Bulk() als veraltet markiert hat API und stellte einen neueren Satz von APIs mit bulkWrite() bereit .

MongoDB Version 3.2 und höher :

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