Si votre serveur MongoDB est 2.6 ou plus récent, il serait préférable d'utiliser une commande d'écriture API de masse
qui permettent l'exécution en masse de update
opérations qui sont simplement des abstractions au-dessus du serveur pour faciliter la création d'opérations en bloc. Ces opérations groupées se présentent principalement sous deux formes :
- Opérations groupées ordonnées . Ces opérations exécutent toutes les opérations dans l'ordre et génèrent une erreur à la première erreur d'écriture.
- Opérations groupées non ordonnées . Ces opérations exécutent toutes les opérations en parallèle et agrègent toutes les erreurs. Les opérations en bloc non ordonnées ne garantissent pas l'ordre d'exécution.
Notez que pour les serveurs plus anciens que 2.6, l'API convertira les opérations. Cependant, il n'est pas possible de convertir à 100 %, il peut donc y avoir des cas extrêmes où il ne peut pas rapporter correctement les bons chiffres.
Pour vos trois cas d'utilisation courants, vous pouvez implémenter l'API de transfert en masse comme ceci :
Cas 1. Changer le type de valeur de la propriété, sans changer la valeur :
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();
});
}
});
Cas 2. Ajouter une nouvelle propriété en fonction de la valeur de la propriété existante :
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();
});
}
});
Cas 3. Ajouter simplement des propriétés de suppression de documents.
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();
});
}
});