2016-08-20 148 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() 
     } 
    } 
})