一尘不染

使用mongoose在MongoDB中批量上传

node.js

是否可以选择使用猫鼬进行批量更新?所以基本上有一个数组,如果不存在则插入每个元素,如果存在则更新它?(我正在使用海关_ids)

当我确实使用 .insert时, MongoDB对于重复的密钥(应更新)返回错误E11000。插入多个新文档可以正常工作:

var Users = self.db.collection('Users');

Users.insert(data, function(err){
            if (err) {
                callback(err);
            }
            else {
                callback(null);
            }
        });

使用 .save 返回错误,该参数必须是单个文档:

Users.save(data, function(err){
   ...
}

这个答案表明没有这样的选择,但是它是针对C#的,并且已经使用了3年。所以我想知道是否有使用猫鼬做这件事的选择?

谢谢!


阅读 341

收藏
2020-07-07

共1个答案

一尘不染

不在具体的“猫鼬”中,或者至少在撰写时尚未。从2.6版本开始,MongoDB shell实际上“在幕后”
使用了“批量操作API
”,就像所有常规辅助方法一样。在其实现中,它首先尝试执行此操作,如果检测到较旧版本的服务器,则对旧版实现会有“退路”。

所有的猫鼬方法“当前”都使用“传统”实现或写关注响应和基本的旧方法。但是.collection,任何给定的猫鼬模型都有一个访问器,该访问器实际上是从底层的“节点本机驱动程序”中访问“集合对象”,而在该节点上本身实现了猫鼬:

 var mongoose = require('mongoose'),
     Schema = mongoose.Schema;

 mongoose.connect('mongodb://localhost/test');

 var sampleSchema  = new Schema({},{ "strict": false });

 var Sample = mongoose.model( "Sample", sampleSchema, "sample" );

 mongoose.connection.on("open", function(err,conn) {

    var bulk = Sample.collection.initializeOrderedBulkOp();
    var counter = 0;

    // representing a long loop
    for ( var x = 0; x < 100000; x++ ) {

        bulk.find(/* some search */).upsert().updateOne(
            /* update conditions */
        });
        counter++;

        if ( counter % 1000 == 0 )
            bulk.execute(function(err,result) {             
                bulk = Sample.collection.initializeOrderedBulkOp();
            });
    }

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

 });

最主要的收获是“猫鼬方法”实际上知道可能尚未真正建立连接,并在完成之前“排队”。您正在“挖掘”的本机驱动程序没有这种区别。

因此,您确实必须意识到以某种方式或形式建立了连接。但是您可以使用本机驱动程序方法,只要您对所做的事情保持谨慎即可。

2020-07-07