Jeśli Twój serwer MongoDB ma wersję 2.6 lub nowszą, lepiej skorzystać z poleceń zapisu Bulk API
które pozwalają na masowe wykonywanie update
operacje, które są po prostu abstrakcjami na wierzchu serwera, aby ułatwić tworzenie operacji zbiorczych. Te operacje masowe występują głównie w dwóch wariantach:
- Zamówione operacje zbiorcze . Te operacje wykonują wszystkie operacje w kolejności i błędach przy pierwszym błędzie zapisu.
- Nieuporządkowane operacje zbiorcze . Operacje te wykonują wszystkie operacje równolegle i agregują wszystkie błędy. Nieuporządkowane operacje zbiorcze nie gwarantują kolejności wykonania.
Uwaga, w przypadku serwerów starszych niż 2.6 interfejs API przekonwertuje operacje w dół. Jednak nie jest możliwe przekonwertowanie w dół w 100%, więc mogą wystąpić pewne skrajne przypadki, w których nie będzie można poprawnie zgłosić prawidłowych liczb.
W przypadku trzech typowych przypadków użycia możesz zaimplementować interfejs Bulk API w następujący sposób:
Przypadek 1. Zmień typ wartości nieruchomości bez zmiany wartości:
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();
});
}
});
Przypadek 2. Dodaj nową nieruchomość na podstawie wartości istniejącej nieruchomości:
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();
});
}
});
Przypadek 3. Po prostu dodaj usuwanie właściwości z dokumentów.
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();
});
}
});