我该如何提高MongoDB的批量性能?

我有这个对象与一些元数据和大量的项目。 我曾经用mongo来存储这个数据,并且通过$unwind数组来查询它。 但是,在极端情况下,arrays变得如此之大,以至于遇到了16MB的BSON限制。

所以我需要将数组的每个元素作为单独的文档存储。 为此,我需要将元数据添加到所有这些元数据,所以我可以找回它们。 build议我为此使用批量操作 。

但是,performance似乎很慢。 插入一个大文件几乎是瞬间的,这需要十秒钟

 var bulk = col.initializeOrderedBulkOp(); var metaData = { hash : hash, date : timestamp, name : name }; // measure time here for (var i = 0, l = array.length; i < l; i++) { // 6000 items var item = array[i]; bulk.insert({ // Apparently, this 6000 times takes 2.9 seconds data : item, metaData : metaData }); } bulk.execute(bulkOpts, function(err, result) { // and this takes 6.5 seconds // measure time here }); 

批量插入总共38 MB的数据(在MongoDB中将其转换为49 MB作为BSON)的6000个文档,性能看起来无法接受。 将元数据附加到每个文档的开销不会那么糟糕,对吧? 更新两个索引的开销不能那么糟糕,对吧?

我错过了什么吗? 有没有更好的方法来插入需要作为一个组提取的文档组?

这不只是我的笔记本电脑。 在服务器上一样。 让我觉得这不是一个configuration错误,而是一个编程错误。

在节点适配器node-mongodb-native 2.0.49使用MongoDB 2.6.11

-update-

只需将元数据添加到大容量帐户中的每个元素2.9秒即可 。 需要有一个更好的方法来做到这一点。

批量发送批量插入操作,因为这会减less到服务器的stream量,从而不通过个别语句发送所有内容,而是分解为可pipe理的块,以实现服务器承诺。 采用这种方法等待callback中的响应的时间也更less。

更好的方法是使用asynchronous模块,因此即使循环input列表也是非阻塞操作。 select批量大小可能会有所不同,但select每1000个条目的批量插入操作将使其安全地保持在16MB BSON硬限制下,因为整个“请求”等于一个BSON文档。

以下演示使用asynchronous模块的同时遍历数组,并重复调用迭代器函数,而testing返回true。 当停止或发生错误时调用callback。

 var bulk = col.initializeOrderedBulkOp(), counter = 0, len = array.length, buildModel = function(index){ return { "data": array[index], "metaData": { "hash": hash, "date": timestamp, "name": name } } }; async.whilst( // Iterator condition function() { return counter < len }, // Do this in the iterator function (callback) { counter++; var model = buildModel(counter); bulk.insert(model); if (counter % 1000 == 0) { bulk.execute(function(err, result) { bulk = col.initializeOrderedBulkOp(); callback(err); }); } else { callback(); } }, // When all is done function(err) { if (counter % 1000 != 0) { bulk.execute(function(err, result) { console.log("More inserts."); }); } console.log("All done now!"); } );