Как обновить и обновить несколько документов в MongoDB с помощью драйверов C#

Я использую MongoDB 2 и хочу обновить несколько документов и добавить значение, например processed:true, в коллекцию. Но API MongoDB С# позволяет нам либо обновлять несколько записей, либо обновлять одну запись.

Как решить эту проблему с помощью API С#?


person Nitin Agarwal    schedule 28.10.2011    source источник
comment
Возможный дубликат драйвера C# mongodb   -  person Mugen    schedule 24.09.2019


Ответы (6)


После 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();
person PUG    schedule 02.12.2014
comment
Наша команда разработчиков использует драйвер -MongoDB 3.0.0 и -MongoDB C# версии 1.7.0.4714. Драйвер MongoDB C# версии 1.7.0.4714 жалуется на то, что InitializeUnorderedBulkOperation() не определен. - person CS Lewis; 12.12.2015
comment
хотя это принятый ответ, он устарел. см. stackoverflow.com/questions/35687470/ - person Mugen; 24.09.2019

Вы не можете сделать это в одном заявлении.

У вас есть два варианта

1) перебираем все объекты и делаем upserts

2) выяснить, какие объекты должны быть обновлены, а какие должны быть вставлены, затем выполните пакетную вставку и множественное обновление.

person jeffsaracco    schedule 28.10.2011

Для тех, кто использует версию 2.0 MongoDB.Driver, вы можете использовать метод 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); 
person Joey    schedule 24.08.2015
comment
Это помогло мне. Большое спасибо. В моем случае я получаю IEnumerable как элементы, которые нужно обновить. BulkWriteAsync принимает IEnumerable, поэтому я изменил его примерно так: var models = items.Select(item => new ReplaceOneModel<T>(new ExpressionFilterDefinition<T>(doc => doc.Id == item.Id), item) { IsUpsert = true }); - person F. Fix; 24.09.2015

Попробуйте сначала удалить все вставляемые элементы из коллекции, а затем вызвать вставку:

        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 ");
                }
            });
        })
person Henry    schedule 22.03.2014
comment
Единственная проблема заключается в том, что клиенты, читающие коллекцию, могут увидеть отсутствующие объекты во время операции. Если ваши клиенты могут это терпеть, то это кажется разумным подходом. - person Tony K.; 05.06.2014

UpdateFlags — это перечисление в драйвере C#, которое позволяет указать оба сразу. Как и любое другое перечисление флагов, вы делаете это с помощью битового «или».

var flags = UpdateFlags.Upsert | UpdateFlags.Multi;

Вы можете прочитать документы по перечислениям здесь (http://msdn.microsoft.com/en-us/library/cc138362.aspx), уделив особое внимание разделу о типах перечислений как битовых флагах.

person Craig Wilson    schedule 16.01.2013

Работа с [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();
}
person Jason Mullings    schedule 16.04.2020