За сравнително малки данни можете да постигнете горното чрез повторение на колекцията с помощта на snapshot
с forEach()
на курсора
метод и актуализиране на всеки документ, както следва:
db.wholesalers.find({
"brands": { "$exists": true, "$type": 4 }
}).snapshot().forEach(function(doc){
db.wholesalers.updateOne(
{ "_id": doc._id },
{ "$set": { "brandsNetherlands": doc.brands } }
);
});
Въпреки че това е оптимално за малки колекции, производителността с големи колекции е значително намалена, тъй като преминаването през голям набор от данни и изпращането на всяка операция за актуализиране на заявка до сървъра води до изчислителна неустойка.
Bulk()
API идва на помощ и значително подобрява производителността, тъй като операциите за запис се изпращат на сървъра само веднъж групово. Ефективността се постига, тъй като методът не изпраща всяка заявка за запис към сървъра (както при текущия израз за актуализиране в forEach()
цикъл), но само веднъж на всеки 1000 заявки, което прави актуализациите по-ефективни и по-бързи, отколкото в момента.
Използвайки същата концепция по-горе с forEach()
цикъл за създаване на партиди, можем да актуализираме колекцията групово, както следва.
В тази демонстрация Bulk()
API, наличен във версии на MongoDB >= 2.6 and < 3.2
използва initializeUnorderedBulkOp()
метод за паралелно изпълнение, както и в недетерминиран ред, на операциите за запис в партидите:
var bulk =db.wholesalers.initializeUnorderedBulkOp(),counter =0; // брояч за следене на размера на партидната актуализация
db.wholesalers.find({
"brands": { "$exists": true, "$type": 4 }
}).snapshot().forEach(function(doc){
bulk.find({ "_id": doc._id }).updateOne({
"$set": { "brandsNetherlands": doc.brands }
});
counter++; // increment counter
if (counter % 1000 == 0) {
bulk.execute(); // Execute per 1000 operations and re-initialize every 1000 update statements
bulk = db.wholesalers.initializeUnorderedBulkOp();
}
});
Следващият пример се отнася за новата версия на MongoDB 3.2
който оттогава е оттеглил Bulk()
API и предостави по-нов набор от API с помощта на bulkWrite()
.
Той използва същите курсори като по-горе, но създава масивите с груповите операции, използвайки същия forEach()
курсорен метод за избутване на всеки документ за групово записване в масива. Тъй като командите за запис могат да приемат не повече от 1000 операции, трябва да групирате операции, за да имате най-много 1000 операции и повторно инициализиране на масива, когато цикълът достигне 1000 итерация:
var cursor = db.wholesalers.find({
"brands": { "$exists": true, "$type": 4 }
}),
bulkUpdateOps = [];
cursor.snapshot().forEach(function(doc){
bulkUpdateOps.push({
"updateOne": {
"filter": { "_id": doc._id },
"update": { "$set": { "brandsNetherlands": doc.brands } }
}
});
if (bulkUpdateOps.length === 1000) {
db.wholesalers.bulkWrite(bulkUpdateOps);
bulkUpdateOps = [];
}
});
if (bulkUpdateOps.length > 0) { db.wholesalers.bulkWrite(bulkUpdateOps); }