In MongoDB zorgt een unieke index ervoor dat een bepaalde waarde in een veld niet in meer dan één document voorkomt. Het zal niet garanderen dat een waarde uniek is in een array binnen een enkel document. Dit wordt hier uitgelegd in de MongoDB-handleiding, waar unieke indexen met meerdere toetsen worden besproken.
Een unieke index zal dus niet aan uw eisen voldoen. Het voorkomt dat afzonderlijke documenten dubbele combinaties bevatten, maar het staat nog steeds toe dat een enkel document dubbele waarden in een array bevat.
De beste optie die u hebt, is uw gegevensmodel te wijzigen om de reeks technologyEmployeeRef-objecten in afzonderlijke documenten te splitsen. Door het op te splitsen in afzonderlijke documenten, kunt u een unieke index gebruiken om uniciteit af te dwingen.
De specifieke implementatie die moet worden gevolgd voor deze wijziging van het gegevensmodel, hangt af van uw toegangspatroon (wat buiten het bereik van deze vraag valt).
Een van die manieren is om een TechnologyEmployee-verzameling te maken die alle velden bevat die momenteel in de technologyEmployeeRef-array bestaan. Bovendien zou deze TechnologyEmployee-verzameling een veld hebben, zoals e-mail, waarmee u het kunt koppelen aan een document in de Employee-verzameling.
Voorbeeld werknemersdocument
{
....
....
"firstName" : "John",
"lastName" : "Doe",
"email" : "[email protected]",
.....
.....
.....
}
Voorbeelddocument werknemertechnologie
{
"email" : "[email protected]",
"technologyCd" : "Java",
"technologyName" : "Java8",
....
.....
"status" : "A"
}
Index in EmployeeTechnology-collectie
{'email' : 1, 'technologyCd' : 1}, {unique: true}
Het nadeel van deze aanpak is dat je uit twee verzamelingen moet lezen om alle gegevens te hebben. Dit nadeel is misschien niet erg als u de gegevens uit beide collecties zelden tegelijkertijd hoeft op te halen. Als u alle gegevens nodig heeft, kan dit worden versneld door gebruik te maken van indexen. Met de indexen zou het versneld kunnen worden door het gebruik van gedekte zoekopdrachten.
Een andere optie is om de gegevens te denormaliseren. U zou dit doen door de werknemersgegevens te dupliceren die u tegelijkertijd met de technologiegegevens nodig hebt.
Voorbeelddocumenten
[
{
....
"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 deze MongoDB-blogpost zeggen ze dat
U zou dit alleen doen voor velden die vaak worden gelezen, veel vaker worden gelezen dan dat ze worden bijgewerkt, en waar u geen sterke consistentie vereist, aangezien het bijwerken van een gedenormaliseerde waarde langzamer, duurder en niet atomair is.
Of, zoals je al zei, kan het zinvol zijn om het datamodel te laten zoals het is en de check op uniciteit aan de applicatiekant uit te voeren. Dit zou u waarschijnlijk de beste leesprestaties kunnen opleveren, maar er zijn enkele nadelen aan verbonden. Ten eerste vertraagt het de schrijfbewerkingen omdat de toepassing enkele controles moet uitvoeren voordat de database kan worden bijgewerkt.
Het is misschien onwaarschijnlijk, maar er is ook een mogelijkheid dat u nog steeds duplicaten krijgt. Als er twee back-to-back-verzoeken zijn om hetzelfde EmployeeTechnology-object in de array in te voegen, kan de validatie van het tweede verzoek worden voltooid (en geslaagd) voordat het eerste verzoek naar de database is geschreven. Ik heb zelf een soortgelijk scenario gezien met een applicatie waaraan ik heb gewerkt. Ook al controleerde de applicatie op uniciteit, als een gebruiker dubbelklikte op een verzendknop, zouden er uiteindelijk dubbele vermeldingen in de database komen. In dit geval verminderde het uitschakelen van de knop bij de eerste klik het risico drastisch. Dit kleine risico kan aanvaardbaar zijn, afhankelijk van uw vereisten en de impact van dubbele invoer.
Welke aanpak het meest logisch is, hangt grotendeels af van uw toegangspatroon en vereisten. Ik hoop dat dit helpt.