MongoDB – 插入,如果它不存在,否则跳过

有条件可以在Mongo中插入吗?

//Pseudo code Bulk Insert Item : If Key exists Skip, don't throw error If key does not exist Add item 

如果我做单插入,它可能会返回一个错误或插入集合中,但它是可能的批量

       

网上收集的解决方案 "MongoDB – 插入,如果它不存在,否则跳过"

你有两个真正的select取决于你想要处理的事情:

  1. 如果密钥数据存在,使用MongoDB的upsertfunction实质上“查找”。 如果没有,那么你只能传入数据到$setOnInsert ,并且不会触及其他任何东西。

  2. 批量使用“未订购”操作。 即使返回错误,整批更新也会继续,但是错误报告就是这样,并且任何不是错误的东西都将被排除。

整个例子:

 var async = require('async'), mongoose = require('mongoose'), Schema = mongoose.Schema; var testSchema = new Schema({ "_id": Number, "name": String },{ "_id": false }); var Test = mongoose.model('Test',testSchema,'test'); mongoose.connect('mongodb://localhost/test'); var data = [ { "_id": 1, "name": "One" }, { "_id": 1, "name": "Another" }, { "_id": 2, "name": "Two" } ]; async.series( [ // Start fresh function(callback) { Test.remove({},callback); }, // Ordered will fail on error. Upserts never fail! function(callback) { var bulk = Test.collection.initializeOrderedBulkOp(); data.forEach(function(item) { bulk.find({ "_id": item._id }).upsert().updateOne({ "$setOnInsert": { "name": item.name } }); }); bulk.execute(callback); }, // All as expected function(callback) { Test.find().exec(function(err,docs) { console.log(docs) callback(err); }); }, // Start again function(callback) { Test.remove({},callback); }, // Unordered will just continue on error and record an error function(callback) { var bulk = Test.collection.initializeUnorderedBulkOp(); data.forEach(function(item) { bulk.insert(item); }); bulk.execute(function(err,result) { callback(); // so what! Could not care about errors }); }, // Still processed the whole batch function(callback) { Test.find().exec(function(err,docs) { console.log(docs) callback(err); }); } ], function(err) { if (err) throw err; mongoose.disconnect(); } ); 

请注意,当前驱动程序中的“已更改的操作”是: .execute()上的结果响应返回一个将被引发的错误对象,而以前的版本在“无序”操作中不会这样做。

这就要求你的代码永远不要依赖于单独返回的err ,而应该把返回的result传回给错误的完整分类。

但是,无序时,无论发生多less错误,批处理都会一直持续到结束。 事情不是一个错误将作为正常承诺。

这真的归结为“序列重要”。 如果是这样,那么你需要“有序”的操作,你只能通过使用“upserts”来避免重复的键。 否则使用“无序”,但要注意错误返回和他们实际上的意思。

另外,使用.collection从基础驱动程序获取底层集合对象以启用“批量”操作时,请始终确保首先调用“某种”mongoose方法。

没有这一点,就没有保证与本地驱动程序方法的数据库连接,因为它是为mongoose方法处理,所以操作将失败,因为没有连接。

首先“发射”mongoose方法的替代方法是将您的应用程序逻辑封装在连接的事件侦听器中:

 mongoose.connection.on("open",function(err) { // app logic in here })