如何使用node.js驱动程序复制mongodb集合?

时间:2014-07-25 23:25:08

标签: javascript node.js mongodb

无论如何通过nodejs mongodb驱动程序复制集合?

即。 collection.copyTo("duplicate_collection");

3 个答案:

答案 0 :(得分:3)

您可以评估copyTo()服务器端虽然它会阻止整个mongod进程,但不会在新集合上创建索引。

var copyTo = "function() { db['source'].copyTo('target') };"

db.eval(copyTo, [], function(err, result) {
  console.log(err);
});

另请注意field type warning

  

“当使用db.collection.copyTo()检查字段类型时,确保操作不会在从BSON转换为JSON期间从文档中删除类型信息。请考虑使用cloneCollection()来维护类型保真度。”

答案 1 :(得分:1)

如果您希望在生产系统上定期执行此操作,请尽量避免.eval()。它很快,但有问题。

更好的方法是使用"Bulk" operations API,并在"async"库的帮助下提供:

db.collection("target",function(err,target) {

    var batch = target.initializeOrderedBulkOp();
    counter = 0;

    var cursor = db.collection("source").find();
    var current = null;       

    async.whilst(
        function() {
            cursor.nextObject(function(err,doc) {
                if (err) throw err;

                // .nextObject() returns null when the cursor is depleted
                if ( doc != null ) {
                    current = doc;
                    return true;
                } else {
                    return false;
                }
            })
        },
        function(callback) {
            batch.insert(current);
            counter++;

            if ( counter % 1000 == 0 ) {
                batch.execute(function(err,result) {    
                    if (err) throw err;
                    var batch = target.initializeOrderedBulkOp();
                    callback();
                });
            }
        },
        function(err) {
            if (err) throw err;
            if ( counter % 1000 != 0 ) 
                batch.execute(function(err,result) {
                    if (err) throw err;

                    // job done
                });
        }
    );    


});

速度快,不如.eval()快,但不会阻止应用程序或服务器。

批处理操作通常会采用与它们相同的操作,但使用模数作为限制器可以实现更多控制,并且基本上避免一次在内存中加载不合理数量的文档。请记住,无论如何,发送的批处理大小在执行之间不能超过16MB。

答案 2 :(得分:0)

复制集合的另一种方法是对集合使用aggregate方法和$out参数。这是async函数内部的示例:

const client = await MongoClient.connect("mongodb://alt_dev:aaaaa:27018/meteor");
const db = client.db('meteor');
const planPrice = await db.collection('plan_price');
const planPriceCopy = await planPrice.aggregate([{$match: {}}, {$out: planPriceUpdateCollection}]);
await planPriceCopy.toArray();

这将创建原始集合及其所有内容的副本。