如何使用 C# 驱动程序在 MongoDB 中更新和插入多个文档

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7934768/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 12:17:28  来源:igfitidea点击:

How to update and upsert multiple documents in MongoDB using C# Drivers

mongodbupsert

提问by Nitin Agarwal

I am using MongoDB 2, and I want to update multiple documents and upsert a value like processed:trueinto the collection. But MongoDB c# api only allows us to either Update Multiple Records or Upsert a single record.

我正在使用 MongoDB 2,我想更新多个文档并将类似的值processed:true插入到集合中。但是 MongoDB c# api 只允许我们更新多个记录或更新单个记录。

How to solve this problem using the C# api?

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

回答by PUG

After Mongo 2.6you can do Bulk Updates/Upserts. Example below does bulk update using c#driver.

Mongo 2.6您可以执行批量更新/更新之后。下面的示例使用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();

回答by jeffsaracco

You cannot do it in one statement.

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

You have two options

你有两个选择

1) loop over all the objects and do upserts

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

2) figure out which objects have to get updated and which have to be inserted then do a batch insert and a multi update

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

回答by Joey

For those using version 2.0 of the MongoDB.Driver, you can make use of the BulkWriteAsync method.

对于使用MongoDB.Driver2.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); 

回答by Henry

Try first removing all items to be inserted from the collection, and then calling 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 ");
                }
            });
        })

回答by Craig Wilson

UpdateFlags is an enum in the C# driver that will let you specify both at once. Just like any other flags enum, you do this by bit "or"ing.

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

var flags = UpdateFlags.Upsert | UpdateFlags.Multi;

You can read the docs on enums here (http://msdn.microsoft.com/en-us/library/cc138362.aspx) paying special attention to the section on Enumeration Types as Bit Flags

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

回答by Jason Mullings

Working with [email protected] - try initializeUnorderedBulkOp():

使用 [email protected] - 尝试 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();
}