Если ваш сервер MongoDB является 2,6 или более поздней версии, было бы лучше воспользоваться помощью команды записи Bulk API, которые позволяют для выполнения объемных update
операции, которые просто абстракции поверх сервера, чтобы сделать легко создавать массовые операции. Эти массовые операции поступают в основном в двух вариантах:
- упорядоченные массовые операции. Эти операции выполняют всю операцию в порядке и ошибки при первой ошибке записи.
- Неупорядоченные массовые операции. Эти операции выполняют все операции параллельно и суммируют все ошибки. Неупорядоченные массовые операции не гарантируют порядок исполнения.
Обратите внимание, что для более старых серверов, чем 2.6, API будет преобразовывать данные из строя. Однако невозможно понизить 100% -ное преобразование, так что могут быть случаи с краем, когда он не может правильно сообщать правильные номера.
Для ваших трех случаев общего пользования, вы могли бы реализовать Bulk API, как это:
Случай 1. Изменить тип стоимости имущества, без изменения значения:
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();
});
}
});
Case 2. Добавить новое свойство на основе значения существующего свойства:
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();
});
}
});
Дело 3. Просто добавление удаляемых свойств из документов.
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();
});
}
});
совершенно, спасибо chridam, пропустили на насыпной API – ezmilhouse
предложений для ускорения кода: (1) использовать ограниченную проекцию на запросе находки, если вам нужно только прикоснуться к одному полю, установите проекцию только для этого поля это ускорит доставку документов на проводе. (2) Как упоминалось в @chridam с использованием обновлений UnorderedBulkOp параллельно, так что это намного быстрее. – marmor