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

Wie implementiere ich diesen mongodb-Abfrage- und Aktualisierungsvorgang (CSharp-Treiber)?

Wenn ich im Wesentlichen Ihren Kern verstehe, möchten Sie im Grunde genommen

  1. Ziehen Sie das nicht benötigte Element aus Ihrem Referenzarray
  2. Setzen Sie den Wert Ihres Hauptreferenzfeldes auf das erste Element des geänderten Arrays

Und das alles in einem einzigen Update, ohne Dokumente über das Internet zu verschieben.

Aber das geht leider nicht. Das Hauptproblem dabei ist, dass es keine Möglichkeit gibt, auf den Wert eines anderen Felds innerhalb des zu aktualisierenden Dokuments zu verweisen. Um dies ohne Iteration zu tun, müssten Sie jedoch auch auf geändert zugreifen Array, um das neue erste Element zu erhalten.

Vielleicht besteht ein Ansatz darin, Ihr Schema zu überdenken, um das zu erreichen, was Sie wollen. Meine Option hier würde Ihre Referenzdokumente ein wenig erweitern und das Hauptreferenzfeld überflüssig machen.

Es scheint, dass die Annahme, mit der Sie bereit sind, bei den Aktualisierungen zu leben, darin besteht, dass Sie die neue Hauptreferenz einfach auf das erste Element im Array setzen können, wenn die entfernte Referenz die Hauptreferenz war. Betrachten Sie in diesem Sinne die folgende Struktur:

refs: [ { oid: "object1" }, { oid: "object2" }, { oid: "object5", main: true } ]

Indem Sie diese in Dokumente mit einem oid ändern Eigenschaft, die auf die ObjectId gesetzt würde, gibt es die Option, eine zusätzliche Eigenschaft für das Dokument zu haben, die angibt, welches die Standardeinstellung ist. Damit lässt sich leicht abfragen, welche Id die Hauptreferenz ist.

Überlegen Sie nun auch, was passieren würde, wenn das Dokument, das mit "object5" im oid-Feld übereinstimmt, aus dem Array gezogen würde:

refs: [ { oid: "object1" }, { oid: "object2" } ]

Wenn Sie also abfragen, was die main-reference ist Gemäß der früheren Logik akzeptieren Sie das erste Dokument im Array. Nun natürlich zu Ihren Anwendungsanforderungen, wenn Sie eine andere main-reference setzen möchten Sie ändern einfach das Dokument

refs: [ { oid: "object1" }, { oid: "object2", main: true } ]

Und jetzt bleibt die Logik übrig, das Array-Element zu wählen, das die Haupteigenschaft als wahr hat, und wie oben gezeigt, dass, wenn diese Eigenschaft in keinem Elementdokument vorhanden ist, auf das erste Element zurückgegriffen wird.

Mit all dem verdaut, wird Ihre Operation, alle Verweise auf ein Objekt aus diesem Array in allen Dokumenten zu ziehen, ziemlich einfach, wie es in der Shell gemacht wird (dasselbe Format sollte im Grunde für jeden Treiber gelten):

db.books.update(
   { "refs.oid": "object5" },
   { $pull: { refs: {oid: "object5"} } }, false, true )

Die beiden zusätzlichen Argumente für die Abfrage- und Aktualisierungsoperation sind upsert und multi beziehungsweise. In diesem Fall upsert macht nicht viel Sinn, da wir nur Dokumente ändern wollen, die existieren, und multi bedeutet, dass wir alle Übereinstimmungen aktualisieren möchten. Standardmäßig wird nur das erste Dokument geändert.

Natürlich habe ich die gesamte Notation gekürzt, aber natürlich können die Werte gemäß Ihrer Absicht tatsächliche ObjectIds sein. Es schien auch vernünftig anzunehmen, dass Ihre Hauptverwendung von main-reference sobald Sie das Dokument abgerufen haben. Definieren einer Abfrage, die die main-reference zurückgibt nach der skizzierten Logik sollte möglich sein, aber so wie es aussieht, habe ich hier viel getippt und muss zum Abendessen eine Pause einlegen :)

Ich denke, dies ist ein lohnendes Argument dafür, Ihr Schema zu überdenken, um Over-the-Wire-Iterationen für das zu vermeiden, was Sie erreichen möchten.