【问题标题】:How to update and upsert multiple documents in MongoDB using C# Drivers如何使用 C# 驱动程序在 MongoDB 中更新和更新多个文档
【发布时间】:2011-12-17 14:22:05
【问题描述】:

我正在使用 MongoDB 2,我想更新多个文档并插入一个像 processed:true 这样的值 进入收藏。但是 MongoDB c# api 只允许我们更新多条记录或 Upsert 一条记录。

如何使用 C# api 解决这个问题?

【问题讨论】:

标签: mongodb upsert


【解决方案1】:

你不能在一个声明中做到这一点。

你有两个选择

1) 遍历所有对象并执行 upserts

2) 找出哪些对象需要更新,哪些需要插入,然后进行批量插入和多次更新

【讨论】:

    【解决方案2】:

    UpdateFlags 是 C# 驱动程序中的一个枚举,可让您同时指定两者。就像任何其他标志枚举一样,您可以通过位“或”来执行此操作。

    var flags = UpdateFlags.Upsert | UpdateFlags.Multi;
    

    您可以在此处 (http://msdn.microsoft.com/en-us/library/cc138362.aspx) 阅读有关枚举的文档,特别注意枚举类型作为位标志的部分

    【讨论】:

      【解决方案3】:

      尝试先从集合中删除所有要插入的项目,然后调用insert:

              var search = [];
              arrayToInsert.forEach(function(v, k) {
                  search.push(v.hash); // my unique key is hash. you could use _id or whatever
              })
              collection.remove({
                  'hash' : {
                      $in : search
                  }
              }, function(e, docs) {
      
                  collection.insert(arrayToInsert, function(e, docs) {
                      if (e) {
                          console.log("data failed to update ", e);
                      }
                      else {
                          console.log("data updated ");
                      }
                  });
              })
      

      【讨论】:

      • 这样做的一个问题是读取集合的客户端可能会在操作期间看到丢失的对象。如果您的客户可以容忍这一点,那么这似乎是一种合理的方法。
      【解决方案4】:

      Mongo 2.6 之后,您可以批量处理Updates/Upserts。下面的示例使用c# 驱动程序进行批量更新。

      MongoCollection<foo> collection = database.GetCollection<foo>(collectionName);
            var bulk = collection.InitializeUnorderedBulkOperation();
            foreach (FooDoc fooDoc in fooDocsList)
            {
              var update = new UpdateDocument { {fooDoc.ToBsonDocument() } };
              bulk.Find(Query.EQ("_id", fooDoc.Id)).Upsert().UpdateOne(update);
            }
            BulkWriteResult bwr =  bulk.Execute();
      

      【讨论】:

      • 我们的开发团队使用 -MongoDB 3.0.0 和 -MongoDB C# Driver Version 1.7.0.4714。 MongoDB C# 驱动程序版本 1.7.0.4714 抱怨 InitializeUnorderedBulkOperation() 未定义。
      • 虽然这是公认的答案,但它已经过时了。见stackoverflow.com/questions/35687470/…
      【解决方案5】:

      对于那些使用MongoDB.Driver 2.0 版的用户,您可以使用BulkWriteAsync 方法。

      <!-- language: c# -->
      // our example list
      List<Products> products = GetProductsFromSomewhere();  
      
      var collection = YourDatabase.GetCollection<BsonDocument>("products"); 
      
      // initialise write model to hold list of our upsert tasks
      var models = new WriteModel<BsonDocument>[products.Count];
      
      // use ReplaceOneModel with property IsUpsert set to true to upsert whole documents
      for (var i = 0; i < products.Count; i++){
          var bsonDoc = products[i].ToBsonDocument();
          models[i] = new ReplaceOneModel<BsonDocument>(new BsonDocument("aw_product_id", products[i].aw_product_id), bsonDoc) { IsUpsert = true };
      };
      
      await collection.BulkWriteAsync(models); 
      

      【讨论】:

      • 这对我有帮助。非常感谢。在我的情况下,我得到一个 IEnumerable 作为要插入的项目。 BulkWriteAsync 需要一个 IEnumerable,所以我将其修改为:var models = items.Select(item =&gt; new ReplaceOneModel&lt;T&gt;(new ExpressionFilterDefinition&lt;T&gt;(doc =&gt; doc.Id == item.Id), item) { IsUpsert = true });
      【解决方案6】:

      使用 mongoose@5.9.9 - 尝试 initializeUnorderedBulkOp():

      export const InfoFunc = (Infos: Infos[]) => {
      
        const bulk = InfoResult.collection.initializeUnorderedBulkOp();
        Infos.forEach((info: Infos) => bulk.find({ "Id": info.Id}).upsert().updateOne(info));
        bulk.execute();
      }
      

      【讨论】:

        猜你喜欢
        • 2021-11-02
        • 1970-01-01
        • 2012-11-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多