将一组文档插入模型中

时间:2014-09-04 04:44:26

标签: javascript node.js mongodb mongodb-query

以下是相关代码:

var Results = mongoose.model('Results', resultsSchema);
var results_array = [];

_.each(matches, function(match) {
    var results = new Results({
        id: match.match_id,
        ... // more attributes
    });
    results_array.push(results);
});
callback(results_array);
});
   }
], function(results_array) {
   results_array.insert(function(err) {
       // error handling

当然,我为No method found获得results_array。但是我不确定还有什么可以调用这个方法。

在其他函数中,我在这里传递等效的results变量,这是一个猫鼬对象并且有insert方法可用。

如何在此处插入文档数组?

**编辑**

function(results_array) {
            async.eachLimit(results_array, 20, function(result, callback) {
                result.save(function(err) {
                    callback(err);
                });
            }, function(err) {
                if (err) {
                    if (err.code == 11000) {
                        return res.status(409);
                    }
                    return next(err);
                }
                res.status(200).end();
                });
            });

所以发生了什么:

当我清除收藏品时,这很好用。 但是,当我重新发送此请求时,我从未收到回复。

这种情况正在发生,因为我的架构不允许来自JSON响应的重复项。因此,当我重新发送请求时,它获得与第一个请求相同的数据,因此会响应错误。这就是我认为状态代码409处理的内容。

我的实施中是否存在拼写错误?

修改2

出现错误代码:

{ [MongoError: insertDocument :: caused by :: 11000 E11000 duplicate key error index:       
test.results.$_id_  dup key: { : 1931559 }]
    name: 'MongoError',
    code: 11000,
    err: 'insertDocument :: caused by :: 11000 E11000 duplicate key error index:    
test.results.$_id_  dup key: { : 1931559 }' }

所以这是预期的。 Mongo正在回复11000错误,抱怨这是一个重复的密钥。

编辑3

if (err.code == 11000) {
    return res.status(409).end();
}

这似乎解决了这个问题。这是一个创可贴修复吗?

1 个答案:

答案 0 :(得分:1)

您似乎在尝试一次插入各种文档。所以你实际上有几个选择。

首先,mongoose中没有.insert()方法,因为它被其他包装替换为.save().create()。这里最基本的过程是在刚刚创建的每个文档上调用“save”。同时在这里使用async库来实现一些流控制,这样一切都不会排队:

async.eachLimit(results_array,20,function(result,callback) {
    result.save(function(err) {
        callback(err)
    });
},function(err) {
   // process when complete or on error
});

另一件事是.create()只能将对象列表作为参数,并在创建文档时简单地插入每个对象:

Results.create(results_array,function(err) {

});

实际上,这将是“原始”对象,因为它们基本上都是作为mongooose文档首先被投射。您可以在回调签名中将这些文档作为附加参数请求,但构建该文件可能有点过分。

无论哪种方式摇动,“异步”形式将并行处理,“创建”形式将按顺序处理,但它们都有效地为每个创建的文档向数据库发出一个“插入”。 / p>

对于真正的批量功能,您目前需要解决基础驱动程序方法,最佳位置是Bulk Operations API

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

    var bulk = Results.collection.initializeUnorderedBulkOp();
    var count = 0;

    async.eachSeries(results_array,function(result,callback) {
        bulk.insert(result);
        count++;

        if ( count % 1000 == 0 ) {
            bulk.execute(function(err,response) {
               // maybe check response
               bulk = Results.collection.initializeUnorderedBulkOp();
               callback(err);
            });
        } else {
            callback();
        }

    },function(err) {
        // called when done
        // Check if there are still writes queued
        if ( count % 1000 != 0 )
            bulk.execute(function(err,response) {
               // maybe check response
            });
    });

});

此处的数组同样是原始对象,而不是那些被转换为mongoose文档的对象。这里没有实现验证或其他mongoose模式逻辑,因为这只是一个基本的驱动方法,并且不知道这些事情。

虽然数组是串行处理的,但上面显示只有每1000个条目处理或到达结束时,写操作才会实际发送到服务器。所以这确实会立即将所有内容发送到服务器。

无序操作意味着通常不会设置err,而“响应”文档将包含可能发生的任何错误。如果您希望第一个错误失败,那么它将是.initializeOrderedBulkOp()

这里需要注意的是,在以这种方式访问​​这些方法之前,必须确保连接已打开。 Mongoose使用它自己的方法来查看连接,因此在对数据库进行实际连接之前,在代码中达到诸如.save()之类的方法,它在等待此事件的意义上“排队”。

因此要么确保首先完成其他“mongoose”操作,要么确保您的应用程序逻辑在确保连接的情况下工作。在此示例中通过放置在“连接打开”事件中进行模拟。

这取决于你真正想做的事情。每个案例都有它的用途,当然最后一个是最快的方式,因为有限的“写”和“返回结果”对话与服务器来回传递。