I MongoDB sikrer et unikt indeks, at en bestemt værdi i et felt ikke er til stede i mere end ét dokument. Det vil ikke garantere, at en værdi er unik på tværs af et array i et enkelt dokument. Dette er forklaret her i MongoDB-manualen, hvor det diskuterer unikke multikey-indekser.
Et unikt indeks vil således ikke opfylde dit krav. Det vil forhindre separate dokumenter i at indeholde duplikerede kombinationer, men det vil stadig tillade et enkelt dokument at indeholde duplikerede værdier på tværs af en matrix.
Den bedste mulighed, du har, er at ændre din datamodel for at opdele rækken af teknologiEmployeeRef-objekter i separate dokumenter. Hvis du deler det op i separate dokumenter, kan du bruge et unikt indeks til at håndhæve unikhed.
Den særlige implementering, der bør tages for denne datamodelændring, vil afhænge af dit adgangsmønster (hvilket er uden for dette spørgsmåls omfang).
En sådan måde dette kunne gøres på er at skabe en TechnologyEmployee-samling, der har alle de felter, der i øjeblikket findes i technologyEmployeeRef-arrayet. Derudover vil denne TechnologyEmployee-samling have et felt, såsom e-mail, som giver dig mulighed for at knytte det til et dokument i Employee-samlingen.
Eksempel på medarbejderdokument
{ .... .... "firstName" :"John", "lastName" :"Doe", "email" :"[email protected]", ..... .. ... .....}
Eksempel på EmployeeTechnology Document
{ "email" :"[email protected]", "technologyCd" :"Java", "technologyName" :"Java8", .... ..... "status" :"A "}
Indeks i EmployeeTechnology-samlingen
{'email' :1, 'technologyCd' :1}, {unique:true}
Ulempen ved denne tilgang er, at du skal læse fra to samlinger for at have alle data. Denne ulempe er måske ikke en stor sag, hvis du sjældent har brug for at hente dataene fra begge samlinger på samme tid. Hvis du har brug for alle data, kan det fremskyndes ved brug af indekser. Med indekserne kunne det fremskyndes yderligere ved brug af dækkede forespørgsler.
En anden mulighed er at denormalisere dataene. Du ville gøre dette ved at duplikere de medarbejderdata, som du skal have adgang til samtidig med teknologidataene.
Eksempeldokumenter
[ { .... "firstName" :"John", "lastName" :"Doe", "email" :"[email protected]", ..... "technologyCd" :" Java", "technologyName" :"Java8", .... "status" :"A" }, { .... "firstName" :"John", "lastName" :"Doe", "e-mail" :" [email protected]", ..... "technologyCd" :"Forår", "technologyName" :"Spring Boot2", .... "status" :"A" }]
I dette MongoDB blogindlæg siger de det
Du ville kun gøre dette for felter, der ofte læses, læses meget oftere, end de bliver opdateret, og hvor du ikke kræver stærk konsistens, da opdatering af en denormaliseret værdi er langsommere, dyrere og ikke er atomær.
Eller som du allerede har nævnt, kan det give mening at lade datamodellen være, som den er, og at udføre kontrollen for unikhed på applikationssiden. Dette kunne sandsynligvis give dig den bedste læseydelse, men det kommer med nogle ulemper. For det første vil det sænke skriveoperationer, fordi applikationen skal køre nogle kontroller, før den kan opdatere databasen.
Det kan være usandsynligt, men der er også en mulighed for, at du stadig kan ende med dubletter. Hvis der er to back-to-back-anmodninger om at indsætte det samme EmployeeTechnology-objekt i arrayet, kan valideringen af den anden anmodning afsluttes (og bestå), før den første anmodning er skrevet til databasen. Jeg har selv set et lignende scenarie med en applikation, jeg arbejdede på. Selvom applikationen tjekkede for unikhed, ville der ende med at være duplikerede poster i databasen, hvis en bruger dobbeltklikkede på en send-knap. I dette tilfælde reducerede deaktivering af knappen ved det første klik drastisk risikoen. Denne lille risiko kan være acceptabel, afhængigt af dine krav og virkningen af at have duplikerede poster.
Hvilken tilgang der giver mest mening afhænger i høj grad af dit adgangsmønster og dine krav. Håber dette hjælper.