MongoDB-如果不存在则插入,否则跳过 [英] MongoDB- Insert if it doesn't exist, else skip

查看:957
本文介绍了MongoDB-如果不存在则插入,否则跳过的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以在条件中插入Mongo;

Is it possible to insert in Mongo with condition;

//Pseudo code

Bulk Insert Item :

If Key exists
    Skip, don't throw error
If key does not exist
    Add item

如果我进行单次插入,可能会在集合中返回错误或插入,但是否可以批量

If i do single inserts, it might return an error or insert in the collection, but is it possible in bulk ?

推荐答案

根据你想要处理的事情,你有两个真正的选择:

You have two real choices here depending on how you want to handle things:


  1. 使用 upsert 功能基本上查找。如果没有,那么您只将数据传递给 $ setOnInsert 并且不会触及任何其他内容。

  1. Use upsert functionality of MongoDB to essentially "lookup" if the key data exists. If not then you only pass in data to $setOnInsert and that will not touch anything else.

批量使用UnOrdered操作。即使返回错误,整批更新仍将继续,但错误报告就是这样,并且任何非错误的内容都将被调整。

Use "UnOrdered" operations in Bulk. The whole batch of updates will continue even if an error is returned, but the error report(s) are just that, and anything that is not an error will be comitted.

整个例子:

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() 返回要抛出的错误对象,其中以前的版本没有使用未订购操作。

Note that the "changed action" in current drivers is that the result response on .execute() will return an error object to be thrown, where previous releases did not do so with "Un-ordered" operations.

这使得您的代码永远不会依赖于单独返回的错误,并且您应该将返回的结果付诸实践而不是完整的错误分类。

This makes it imperative that your code never relies on the err returned alone, and you should be inpspeting the returned result instead for the full classification of errors.

尽管如此,无序时,无论发生多少错误,批处理都会一直持续到结束。不是错误的事情将照常正常进行。

Nonetheless, when unordered then the batch continues until the end, no matter how many errors occur. Things that are not an error will be committed as normal.

这实际上归结为序列重要。如果是这样,那么您需要有序操作,并且您只能通过使用upserts来避免重复键。否则使用无序,但要注意错误返回以及它们实际意味着什么。

This really comes down to "is sequence important". If so, then you need "Ordered" operations and you can only avoid duplicate keys by using "upserts". Otherwise use "unordered", but be aware of the error returns and what they actually mean.

此外,当使用 .collection 从基本驱动程序获取底层集合对象以启用批量操作,然后始终确保始终首先调用某些mongoose方法。

Also, when using .collection to get the underlying collection object from the base driver to enable "Bulk" operations, then always be sure that either "some" mongoose method has always been called first.

没有它,就没有保证使用本机驱动程序方法连接数据库,因为它是为mongoose方法处理的,因此操作将因无连接而失败。

Without that, there is no guaranteed connection to the database with the native driver methods as it is handled for the mongoose methods, so the operation will fail due to no connection.

首先触发mongoose方法的替代方法是将您的app逻辑包装在事件监听器中以进行连接:

The alternate to "firing" a mongoose method first, is to wrap your app logic in an event listener for the connection:

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

这篇关于MongoDB-如果不存在则插入,否则跳过的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆