我正在使用最新的 Node.js native 驱动程序 (2.0) 批量插入大量文档。
我的集合在 URL 字段上有一个索引,并且我一定会从插入的数千行中获取重复项。有没有办法让 MongoDB 在遇到重复时不崩溃?
现在我一次批处理 1000 条记录,并使用 insertMany。我尝试了各种方法,包括添加 {continueOnError=true}。我尝试了一条一条地插入我的记录,但是速度太慢了,我有成千上万的工作人员在排队,我真的无法承受延迟。
集合定义:
self.prods = db.collection('products');
self.prods.ensureIndex({url:1},{unique:true}, function() {});
插入:
MongoProcessor.prototype._batchInsert= function(coll,items){
var self = this;
if(items.length>0){
var batch = [];
var l = items.length;
for (var i = 0; i < 999; i++) {
if(i<l){
batch.push(items.shift());
}
if(i===998){
coll.insertMany(batch, {continueOnError: true},function(err,res){
if(err) console.log(err);
if(res) console.log('Inserted products: '+res.insertedCount+' / '+batch.length);
self._batchInsert(coll,items);
});
}
}
}else{
self._terminate();
}
};
我正在考虑在插入之前删除索引,然后使用 dropDups 重新索引,但这似乎有点老套,我的工作人员是群集的,我不知道如果他们在另一个进程正在重新索引时尝试插入记录会发生什么...有人有更好的主意吗?
编辑:
我忘了提一件事。我插入的项目有一个“已处理”字段,该字段设置为“假”。然而,数据库中已有的项目可能已被处理,因此该字段可以为“true”。因此我无法更新插入...或者我可以选择一个不被更新插入影响的字段吗?
最佳答案
2.6 Bulk API是您正在寻找的,这将需要 MongoDB 2.6+* 和 Node 驱动程序 1.4+。
批量操作有两种类型:
- 有序批量操作。这些操作按顺序执行所有操作,并在第一个写入错误时出错。
- 无序批量操作。这些操作并行执行所有操作并汇总所有错误。无序的批量操作不保证执行顺序。
所以在你的情况下Unordered就是你想要的。前面的链接提供了一个示例:
MongoClient.connect("mongodb://localhost:27017/test", function(err, db) {
// Get the collection
var col = db.collection('batch_write_ordered_ops');
// Initialize the Ordered Batch
var batch = col.initializeUnorderedBulkOp();
// Add some operations to be executed in order
batch.insert({a:1});
batch.find({a:1}).updateOne({$set: {b:1}});
batch.find({a:2}).upsert().updateOne({$set: {b:2}});
batch.insert({a:3});
batch.find({a:3}).remove({a:3});
// Execute the operations
batch.execute(function(err, result) {
console.dir(err);
console.dir(result);
db.close();
});
});
<小时/>
*文档确实指出:“对于 2.6 之前的旧服务器,API 将对操作进行下转换。但是不可能 100% 下转换,因此可能会出现轻微的边缘情况无法正确报告正确的数字。”
关于node.js - 插入记录而不会因重复而失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26668648/