Se il tuo server MongoDB è 2.6 o successivo, sarebbe meglio sfruttare i comandi di scrittura API in blocco
che consentono l'esecuzione di massa update
operazioni che sono semplicemente astrazioni sulla parte superiore del server per semplificare la creazione di operazioni in blocco. Queste operazioni sfuse sono disponibili principalmente in due gusti:
- Operazioni in blocco ordinate . Queste operazioni eseguono tutte le operazioni in ordine ed escono dal primo errore di scrittura.
- Operazioni in blocco non ordinate . Queste operazioni eseguono tutte le operazioni in parallelo e aggregano tutti gli errori. Le operazioni in blocco non ordinate non garantiscono l'ordine di esecuzione.
Nota, per i server più vecchi di 2.6 l'API eseguirà la downconversion delle operazioni. Tuttavia non è possibile effettuare una conversione al 100%, quindi potrebbero esserci alcuni casi limite in cui non è possibile riportare correttamente i numeri corretti.
Per i tuoi tre casi d'uso comuni, potresti implementare l'API in blocco in questo modo:
Caso 1. Modifica il tipo di valore della proprietà, senza modificare il valore:
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();
});
}
});
Caso 2. Aggiungi una nuova proprietà in base al valore della proprietà esistente:
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();
});
}
});
Caso 3. Semplicemente aggiungendo proprietà di rimozione dai documenti.
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();
});
}
});