2016-08-20 137 views
2

我已经搜索并找不到关于如何在使用批量插入时忽略重复错误的任何可靠信息。MongoDB批量插入忽略重复

这里是我目前使用的代码:

MongoClient.connect(mongoURL, function(err, db) { 
     if(err) console.err(err) 
     let col = db.collection('user_ids') 
     let batch = col.initializeUnorderedBulkOp() 

     ids.forEach(function(id) { 
     batch.insert({ userid: id, used: false, group: argv.groupID }) 
     }) 

     batch.execute(function(err, result) { 
     if(err) { 
      console.error(new Error(err)) 
      db.close() 
     } 

     // Do some work 

     db.close() 
     }) 
    }) 

这可能吗?我已经尝试将{continueOnError: true, safe: true}加到bulk.insert(...),但那没有奏效。

任何想法?

回答

2

一种替代方法是使用bulk.find().upsert().replaceOne()代替:

MongoClient.connect(mongoURL, function(err, db) { 
    if(err) console.err(err) 
    let col = db.collection('user_ids') 
    let batch = col.initializeUnorderedBulkOp() 

    ids.forEach(function(id) {   
     batch.find({ userid: id }).upsert().replaceOne({ 
      userid: id, 
      used: false, 
      group: argv.groupID 
     }); 
    }); 

    batch.execute(function(err, result) { 
     if(err) { 
      console.error(new Error(err)) 
      db.close() 
     } 

     // Do some work 

     db.close() 
    }); 
}); 

利用上述,如果文档的查询{ userid: id }它会与新的文档来替换相匹配,否则它会被创建,因此不存在重复抛出重要错误。


MongoDB的服务器版本3.2+,使用bulkWrite为:

MongoClient.connect(mongoURL, function(err, db) { 

    if(err) console.err(err) 

    let col = db.collection('user_ids') 
    let ops = [] 
    let counter = 0 

    ids.forEach(function(id) { 
     ops.push({ 
      "replaceOne": { 
       "filter": { "userid": id }, 
       "replacement": { 
        userid: id, 
        used: false, 
        group: argv.groupID 
       }, 
       "upsert": true 
      } 
     }) 

     counter++ 

     if (counter % 500 === 0) { 
      col.bulkWrite(ops, function(err, r) { 
       // do something with result 
       db.close() 
      }) 
      ops = [] 
     } 
    }) 

    if (counter % 500 !== 0) { 
     col.bulkWrite(ops, function(err, r) { 
      // do something with result 
      db.close() 
     } 
    } 
})