MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Aktualisieren des Wörterbuchs in Mongodb

Nicht sicher, was genau Sie wollen. Es gibt im Wesentlichen zwei Arten von Updates in MongoDB:Sie können ein atomares Update durchführen , oder das Dokument ersetzen .

Das Ersetzen des Dokuments ist oft einfacher , weil es Ihnen erlaubt, C#-Standardoperationen zu verwenden, um Änderungen vorzunehmen, und es wird generierte Eigenschaften und dergleichen neu auswerten:

var user = new User { Name = "John Doe", Quests = 
   new Dictionary<string, Tuple<string, string>> { 
       { "hoho", new Tuple<string, string>("A", "A-Item") } } };
users.InsertOneAsync(user).Wait();
user.Quests = new Dictionary<string, Tuple<string, string>> { 
       { "hoho Modified", new Tuple<string, string>("B", "B-Item") } };
users.ReplaceOneAsync(p => p.Id == user.Id, user);

Es ist jedoch manchmal erforderlich, atomare Modifikatoren wie $push zu verwenden , $pull , $set , $addToSet , etc. aufgrund von Parallelitätsbedenken. Ich halte es im Allgemeinen für eine schlechte Idee, komplexe Operationen auf komplexe eingebettete Objekte auf diese Weise durchzuführen, da die Wahrscheinlichkeit hoch ist, dass das Objekt konsistenz ist (im Sinne von ACID oder 'Objektinvarianten' ) kann nicht überprüft werden.

Angenommen, ein Benutzer sollte nicht mehr als 3 aktive Quests gleichzeitig haben dürfen, wer stellt sicher, dass diese Regel eingehalten wird? Dafür ist normalerweise der Code zuständig, und komplexe Invarianten können nicht von der Datenbank überprüft werden.

Wenn Sie diese atomaren Operatoren dennoch verwenden möchten, schlage ich vor, dass Sie eine neue Frage stellen, da es dort wirklich auf die Details ankommt (das Wörterbuch wird standardmäßig als Dokument serialisiert, das Tupel als Array, und sie erfordern unterschiedliche atomare Modifikatoren in MongoDB). Um beispielsweise ein neues Element zum Wörterbuch hinzuzufügen, verwenden Sie $set :

users.UpdateOneAsync(p => p.Id == user.Id, 
  Builders<User>.Update.Set("Quests.hoho Modified", 
     new Tuple<string, string>("B", "B-Item")));