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

Spring Data Mongo - Wenden Sie eindeutige Kombinationsfelder im eingebetteten Dokument an

In MongoDB stellt ein eindeutiger Index sicher, dass ein bestimmter Wert in einem Feld nicht in mehr als einem Dokument vorhanden ist. Es wird nicht garantieren, dass ein Wert innerhalb eines Arrays innerhalb eines einzelnen Dokuments eindeutig ist. Dies wird hier im MongoDB-Handbuch erklärt, wo eindeutige Multikey-Indizes behandelt werden.

Daher wird ein eindeutiger Index Ihre Anforderung nicht erfüllen. Es wird verhindern, dass separate Dokumente doppelte Kombinationen enthalten, aber es wird immer noch zulassen, dass ein einzelnes Dokument doppelte Werte in einem Array enthält.

Die beste Option, die Sie haben, besteht darin, Ihr Datenmodell so zu ändern, dass das Array von technologyEmployeeRef-Objekten in separate Dokumente aufgeteilt wird. Wenn Sie es in separate Dokumente aufteilen, können Sie einen eindeutigen Index verwenden, um die Eindeutigkeit zu erzwingen.

Die jeweilige Implementierung, die für diese Datenmodelländerung vorgenommen werden sollte, hängt von Ihrem Zugriffsmuster ab (das nicht Gegenstand dieser Frage ist).

Eine solche Möglichkeit besteht darin, eine TechnologyEmployee-Sammlung zu erstellen, die alle Felder enthält, die derzeit im Array technologyEmployeeRef vorhanden sind. Außerdem hätte diese TechnologyEmployee-Sammlung ein Feld, z. B. E-Mail, mit dem Sie sie einem Dokument in der Employee-Sammlung zuordnen könnten.

Beispiel für ein Mitarbeiterdokument

{
  ....
  ....
  "firstName" : "John",
  "lastName" : "Doe",
  "email" : "[email protected]",
  .....
  .....
  .....
}

Beispieldokument für EmployeeTechnology

{
  "email" : "[email protected]",
  "technologyCd" : "Java",
  "technologyName" : "Java8",
  ....
  .....
  "status" : "A"
}

Index in der EmployeeTechnology-Sammlung

{'email' : 1, 'technologyCd' : 1}, {unique: true}

Der Nachteil dieses Ansatzes besteht darin, dass Sie aus zwei Sammlungen lesen müssten, um alle Daten zu erhalten. Dieser Nachteil ist möglicherweise keine große Sache, wenn Sie selten die Daten aus beiden Sammlungen gleichzeitig abrufen müssen. Wenn Sie alle Daten benötigen, kann dies durch die Verwendung von Indizes beschleunigt werden. Mit den Indizes könnte es durch die Verwendung von verdeckten Abfragen weiter beschleunigt werden.

Eine weitere Möglichkeit besteht darin, die Daten zu denormalisieren. Dazu würden Sie die Mitarbeiterdaten duplizieren, auf die Sie gleichzeitig mit den Technologiedaten zugreifen müssen.

Musterdokumente

[
  {
    ....
    "firstName" : "John",
    "lastName" : "Doe",
    "email" : "[email protected]",
    .....
    "technologyCd" : "Java",
    "technologyName" : "Java8",
    ....
    "status" : "A"
  },
  {
    ....
    "firstName" : "John",
    "lastName" : "Doe",
    "email" : "[email protected]",
    .....
    "technologyCd" : "Spring",
    "technologyName" : "Spring Boot2",
    ....
    "status" : "A"
  }
]

In diesem MongoDB-Blogpost heißt es, dass

Sie würden dies nur für Felder tun, die häufig gelesen werden, viel öfter gelesen als aktualisiert werden und wo Sie keine starke Konsistenz benötigen, da das Aktualisieren eines denormalisierten Werts langsamer, teurer und nicht atomar ist.

Oder wie Sie bereits erwähnt haben, kann es sinnvoll sein, das Datenmodell so zu lassen, wie es ist, und die Überprüfung auf Eindeutigkeit auf der Anwendungsseite durchzuführen. Dies könnte Ihnen wahrscheinlich die beste Leseleistung bieten, bringt jedoch einige Nachteile mit sich. Erstens werden Schreibvorgänge verlangsamt, da die Anwendung einige Überprüfungen durchführen muss, bevor sie die Datenbank aktualisieren kann.

Es mag unwahrscheinlich sein, aber es besteht auch die Möglichkeit, dass Sie immer noch Duplikate erhalten. Wenn es zwei aufeinanderfolgende Anforderungen zum Einfügen desselben EmployeeTechnology-Objekts in das Array gibt, kann die Überprüfung der zweiten Anforderung abgeschlossen (und erfolgreich) sein, bevor die erste Anforderung in die Datenbank geschrieben wurde. Ich habe selbst ein ähnliches Szenario mit einer Anwendung gesehen, an der ich gearbeitet habe. Obwohl die Anwendung die Eindeutigkeit überprüfte, würde ein Doppelklick auf die Schaltfläche „Senden“ zu doppelten Einträgen in der Datenbank führen. In diesem Fall reduzierte das Deaktivieren der Schaltfläche beim ersten Klick das Risiko drastisch. Dieses geringe Risiko kann je nach Ihren Anforderungen und den Auswirkungen doppelter Einträge tolerierbar sein.

Welcher Ansatz am sinnvollsten ist, hängt maßgeblich von Ihrem Zugriffsmuster und Ihren Anforderungen ab. Hoffe das hilft.