javascript - 使用 Node.js 将许多记录插入 Mongodb 的正确方法

标签 javascript node.js mongodb

我想知道使用 Node.js 向 Mongodb(尽管可以是任何其他数据库)进行批量插入的正确方法是什么

我已经编写了以下代码作为示例,尽管我认为它是错误的,因为 db.close() 可能在所有异步 collection.insert 调用完成之前运行。

MongoClient.connect('mongodb://127.0.0.1:27017/test', function (err, db) {
    var i, collection;
    if (err) {
        throw err;
    }
    collection = db.collection('entries');
    for (i = 0; i < entries.length; i++) {
        collection.insert(entries[i].entry);
    }
    db.close();
});

最佳答案

如果您的 MongoDB 服务器是 2.6 或更高版本,最好利用写入命令 Bulk API 允许执行批量插入操作,这些操作只是服务器顶部的抽象,可以轻松构建批量操作,从而通过对大型集合的更新获得性能提升。

批量发送批量插入操作会减少到服务器的流量,从而通过不在单独的语句中发送所有内容,而是分解成可管理的 block 以供服务器提交,从而执行高效的电汇事务。使用这种方法等待回调中响应的时间也更少。

这些批量操作主要有两种形式:

  • 有序批量操作。这些操作按顺序执行所有操作,并在第一次写入错误时出错。
  • 无序批量操作。这些操作并行执行所有操作并聚合所有错误。无序批量操作不保证执行顺序。

注意,对于早于 2.6 的旧服务器,API 将下转换操作。但是,不可能进行 100% 的下转换,因此可能存在一些无法正确报告正确数字的极端情况。

在您的情况下,您可以像这样以 1000 个批量实现批量 API 插入操作:

对于 MongoDB 3.2+ 使用 bulkWrite

var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017/test';
var entries = [ ... ] // a huge array containing the entry objects

var createNewEntries = function(db, entries, callback) {

    // Get the collection and bulk api artefacts
    var collection = db.collection('entries'),          
        bulkUpdateOps = [];    

    entries.forEach(function(doc) {
        bulkUpdateOps.push({ "insertOne": { "document": doc } });

        if (bulkUpdateOps.length === 1000) {
            collection.bulkWrite(bulkUpdateOps).then(function(r) {
                // do something with result
            });
            bulkUpdateOps = [];
        }
    })

    if (bulkUpdateOps.length > 0) {
        collection.bulkWrite(bulkUpdateOps).then(function(r) {
            // do something with result
        });
    }
};

对于 MongoDB <3.2

var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017/test';
var entries = [ ... ] // a huge array containing the entry objects

var createNewEntries = function(db, entries, callback) {

    // Get the collection and bulk api artefacts
    var collection = db.collection('entries'),          
        bulk = collection.initializeOrderedBulkOp(), // Initialize the Ordered Batch
        counter = 0;    

    // Execute the forEach method, triggers for each entry in the array
    entries.forEach(function(obj) {         

        bulk.insert(obj);           
        counter++;

        if (counter % 1000 == 0 ) {
            // Execute the operation
            bulk.execute(function(err, result) {  
                // re-initialise batch operation           
                bulk = collection.initializeOrderedBulkOp();
                callback();
            });
        }
    });             

    if (counter % 1000 != 0 ){
        bulk.execute(function(err, result) {
            // do something with result 
            callback();             
        }); 
    } 
};

调用 createNewEntries() 函数。

MongoClient.connect(url, function(err, db) {
    createNewEntries(db, entries, function() {
        db.close();
    });
});

关于javascript - 使用 Node.js 将许多记录插入 Mongodb 的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34530348/

相关文章:

javascript - Meteor.call 从 _.wrapAsync 函数返回时返回未定义

javascript - 单击按钮后获取所有输入字段值。 ( JavaScript )

javascript - 如何在没有express的情况下在nodejs中使用网络IP而不是localhost?

javascript - 如何在保存到 Mongoose (ExpressJS) 之前格式化模型中的数据

javascript - 为什么闭包编译器会覆盖短的 var ref。到 'this' 关键字并恢复 'this' ?

javascript - 将产品添加到购物车时,会为产品添加默认选项,但不会添加选定的选项

node.js - 如何使用 async.map

node.js - ionic 错误 : SPAWN EACCES

javascript - mongodb聚合如何获取所有字段

mongodb - 我怎样才能从数组中删除重复的项目(复杂对象)