2011-10-28 3 views

risposta

12

Non è possibile farlo in un'unica istruzione.

Si hanno due opzioni

1) un ciclo su tutti gli oggetti e fare upserts

2) capire quali oggetti devono ottenere aggiornato e che devono essere inseriti poi fare un inserto batch e un multi update

1

UpdateFlags è un enum nel driver C# che consente di specificare entrambi contemporaneamente. Proprio come qualsiasi altro enumeratore di bandiere, lo fai per bit "o" ing.

var flags = UpdateFlags.Upsert | UpdateFlags.Multi; 

È possibile leggere la documentazione su enumerazioni qui (http://msdn.microsoft.com/en-us/library/cc138362.aspx) con particolare attenzione alla sezione tipi di enumerazione come bit Bandiere

1

Prova prima di rimuovere tutti gli elementi da inserire dalla raccolta, e quindi chiamando inserto:

 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 "); 
       } 
      }); 
     }) 
+2

L'unico problema è che i client che leggono la raccolta possono vedere oggetti mancanti durante l'operazione. Se i tuoi clienti possono tollerarlo, allora questo sembra un approccio ragionevole. –

14

Dopo Mongo 2.6 si può fare Bulk Updates/Upserts. L'esempio sotto fa l'aggiornamento collettivo usando il driver 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(); 
+0

Il nostro team di sviluppo utilizza -MongoDB 3.0.0 e -MongoDB C# Driver versione 1.7.0.4714. La versione 1.7.0.4714 del driver MongoDB C# si lamenta del fatto che InitializeUnorderedBulkOperation() non è definito. –

4

Per coloro che utilizzano la versione 2.0 del MongoDB.Driver, si può fare uso del metodo 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); 
+3

Questo mi ha aiutato. Molte grazie. Nel mio caso ottengo un oggetto IEnumerable come articoli da sottoporre a upsert. 'BulkWriteAsync' accetta un oggetto IEnumerable, quindi l'ho modificato in qualcosa del genere:' var models = items.Select (item => new ReplaceOneModel (new ExpressionFilterDefinition (doc => doc.Id == item.Id), item) {IsUpsert = true}); ' –