使用asynchronous批量插入在MongoDb中自动增加字段

我正在看这篇关于在MongoDb中自动递增字段的文章。 http://docs.mongodb.org/manual/tutorial/create-an-auto-incrementing-field/

这在理论上看起来不错,但是在我的应用程序中,所有数据库调用都是asynchronous的。 Ps,我使用Mongoskin。 考虑一下:

var getNextSequence function (name) { db.counters.findAndModify({_id: 'invoiceNr'}, {}, {$inc: {seq: 1}}, {new: true}, function(err, doc) { if (err) { return next(err); } return doc.seq; }); }; var seq = getNextSequence('invoiceNr'); console.log(seq); 

这(Console.log)执行时当然没有任何价值…

这让我想到了嵌套的callback(经典的Node风格):

 db.counters.findAndModify({_id: 'invoiceNr'}, {}, {$inc: {seq: 1}}, {new: true}, function(err, doc) { if (err) { return next(err); } var seq = getNextSequence('invoiceNr'); // Do something with the seq, like using it when inserting another document. }); 

这将工作正常的一个文件,但我不能看到如何做到这一点,如果我做一个批量插入(传递一个数组插入)。 我需要批量插入。

回到循环和单插入不似乎是一个很好的解决scheme。

你有什么好的解决scheme吗?

所以文档build议.findAndModify()对于这种types的操作,因为“更新/递增”和检索结果的操作是“primefaces”操作。 当然,如果你一次插入500个文件,你不想回到500次“下一个增量”,因为这是疯狂的。 但是你错过了这个概念。

谁说你必须增加1 ? 简单地说,当你知道你插入了500个项目时,你只需要将当前计数器增加501,以便下一个要求下一个计数器值的操作获得已经增加了501的值,好的。

现在你问柜台增加了一个500块,基本上只是用它们。 所以你知道第一个使用的值基本上是从你的返回值减去500开始的,而你想结束插入到实际返回的值。

所以你需要这样的代码:

 var async = require('async'), mongo = require('mongoskin'), db = mongo.db('mongodb://localhost/test'); // The general incrementer function getNextSequence( name, increment, callback ) { // Handling passing in "increment" as optional var args = Array.prototype.slice.call(arguments, 1); callback = args.pop(); increment = args.length ? args.shift() || 1 : 1; // default 1 db.collection('counters').findAndModify( { "_id": name }, {}, { "$inc": { "seq": increment } }, { "new": true, "upsert": true }, function(err,doc) { callback(err,doc.seq); } ); } // Meat of your insertion logic db.collection('target',function(err, collection) { var arrayToInsert = []; // simulating, but 500 items long assumed for (var x=0; x < 500; x++) { arrayToInsert.push({ "x": x }); } var bulk = collection.initializeOrderedBulkOp(); async.waterfall( [ function(callback) { getNextSequence('invoiceNo',arrayToInsert.length + 1,callback); }, function(seq,callback) { var current = seq - arrayToInsert.length; var index = 0; async.whilst( function() { return index < arrayToInsert.length }, function(callback) { doc = arrayToInsert[index]; doc["invoice"] = current; bulk.insert( doc ); index++; current++ callback(); }, function(err) { bulk.execute(callback); } ); } ], function(err,result) { if (err) throw err; // Log BulkWrite result console.log( JSON.stringify( result, undefined, 2 ) ); } ); }); 

那么,这是基本的模拟器,但你应该明白了。 从本质上来说,只需要在插入实际文档的时候获取一个“值”块,以指定要插入多less个条目并使用每个“值”。

最坏的情况? 插入失败的地方,并不是所有的价值观结束在文件。 所以呢? 没关系,因为你已经增加了计数器,没有其他进程可以从计数器中获取相同的“值”。

正如你可以从评论中收集的,这是我试图带领你的地方,你可能已经完成了基础知识。 没有什么说你不能把这个计数器递增1以上,所以只需要增加你想要的数量。