12/06/2020
At arbejde med databaser indebærer uundgåeligt, at data skal ændres over tid. I MongoDB, en populær NoSQL-database, er opdatering af dokumenter en fundamental og hyppig operation. Uanset om du skal rette en simpel tastefejl, tilføje ny information til et eksisterende dokument eller udføre masseopdateringer på tværs af en hel samling, tilbyder MongoDB et robust sæt af metoder og operatorer til at håndtere enhver situation. At forstå disse forskellige værktøjer er afgørende for at kunne vedligeholde en sund og nøjagtig database. Denne artikel vil guide dig igennem de mest almindelige og effektive måder at opdatere felter og dokumenter i MongoDB, fra de grundlæggende kommandoer til mere avancerede teknikker.

- Forberedelse af vores testdatabase
- Opdatering af et enkelt dokument med updateOne()
- Opdatering af flere dokumenter med updateMany()
- Udskiftning af et helt dokument med replaceOne()
- Avancerede metoder: Find og opdater i én operation
- Vigtige opdateringsoperatorer
- Upsert: Opdatering eller indsættelse
- Ofte Stillede Spørgsmål (FAQ)
Forberedelse af vores testdatabase
For at illustrere de forskellige opdateringsmetoder, lad os først oprette en simpel database og en samling (collection). Vi forestiller os en samling kaldet studerende i en database ved navn universitet. Lad os indsætte to dokumenter, som vi kan arbejde med:
db.studerende.insertMany([ { "studie_id": 8764, "navn": "Peter Jensen", "adresse": "Kollegie A", "alder": 21, "studienr": 199406 }, { "studie_id": 8765, "navn": "Mette Nielsen", "adresse": "Kollegie B", "alder": 23, "studienr": 199408 } ]);Med disse data på plads er vi klar til at udforske de forskellige måder, vi kan modificere dem på.
Opdatering af et enkelt dokument med updateOne()
Den mest almindelige opgave er at opdatere et enkelt felt i et specifikt dokument. Til dette formål er metoden updateOne() ideel. Den finder det første dokument, der matcher et givent filter, og anvender de specificerede ændringer.
Metodens struktur er: db.collection.updateOne(<filter>, <update>, <options>).
- Filter: Et dokument, der specificerer betingelserne for at finde det dokument, der skal opdateres.
- Update: Et dokument, der specificerer de ændringer, der skal foretages, ved hjælp af opdateringsoperatorer som
$set.
Lad os sige, at Peter Jensen er flyttet til et nyt kollegie. Vi kan opdatere hans adresse således:
db.studerende.updateOne( { "navn": "Peter Jensen" }, { $set: { "adresse": "Kollegie C" } } );Her specificerer det første argument { "navn": "Peter Jensen" }, at vi leder efter dokumentet, hvor feltet navn har værdien "Peter Jensen". Det andet argument bruger $set-operatoren til at angive, at feltet adresse skal have den nye værdi "Kollegie C". Hvis feltet adresse ikke eksisterede i forvejen, ville $set oprette det.
Resultatet af denne kommando vil typisk se sådan ud:
{ "acknowledged": true, "matchedCount": 1, "modifiedCount": 1 }Dette output bekræfter, at kommandoen blev genkendt (acknowledged), at ét dokument matchede vores filter (matchedCount), og at ét dokument blev ændret (modifiedCount).
Opdatering af flere dokumenter med updateMany()
Nogle gange har man brug for at opdatere flere dokumenter på én gang. Forestil dig, at vi vil tilføje et nyt felt, status, med værdien "Aktiv" til alle studerende, der er under 25 år. Her er updateMany() det perfekte værktøj.
Syntaksen er identisk med updateOne(), men metoden anvender opdateringen på *alle* dokumenter, der matcher filteret.
db.studerende.updateMany( { alder: { $lt: 25 } }, { $set: { "status": "Aktiv" } } );I dette eksempel bruger vi $lt (less than) operatoren til at finde alle studerende, hvis alder er mindre end 25. Derefter bruger vi $set til at tilføje det nye felt status til alle disse dokumenter. Da begge vores test-studerende er under 25, vil outputtet vise, at to dokumenter blev fundet og modificeret:
{ "acknowledged": true, "matchedCount": 2, "modifiedCount": 2 }Udskiftning af et helt dokument med replaceOne()
I sjældnere tilfælde kan det være nødvendigt at erstatte et helt dokument med et nyt, men bevare det oprindelige _id. Metoden replaceOne() gør netop dette. Det er dog vigtigt at være forsigtig: alle felter fra det oprindelige dokument, undtagen _id, vil blive slettet og erstattet med felterne i det nye dokument.

Lad os antage, at vi har modtaget fuldstændig opdateret information om Mette Nielsen og vil erstatte hendes gamle dokument.
db.studerende.replaceOne( { "studie_id": 8765 }, { "studie_id": 8765, "navn": "Mette N. Hansen", "adresse": "Kollegie D", "alder": 24, "studienr": 199408, "fag": "Datalogi" } );Efter denne operation vil Mette Nielsens dokument nu indeholde det nye felt fag, men det felt status, vi tilføjede tidligere, vil være forsvundet, fordi det ikke var med i erstatningsdokumentet.
Avancerede metoder: Find og opdater i én operation
MongoDB tilbyder også metoder, der kombinerer en søgning med en opdatering og returnerer det originale eller det opdaterede dokument. Dette er yderst nyttigt i applikationer, hvor man skal handle på data, som de så ud før eller efter en ændring.
findOneAndUpdate()
Denne metode finder det første dokument, der matcher et filter, opdaterer det og returnerer enten det oprindelige eller det nye dokument. Dette er ideelt, når man f.eks. skal behandle et job i en kø og markere det som "behandles".
Lad os sige, vi vil forhøje Peter Jensens studienummer med 1 og se, hvad det var *før* ændringen.
db.studerende.findOneAndUpdate( { "studie_id": 8764 }, { $inc: { "studienr": 1 } } );Her bruger vi $inc (increment) operatoren til at lægge 1 til den nuværende værdi af studienr. Som standard returnerer denne kommando dokumentet, som det så ud *før* opdateringen. Man kan tilføje en option { returnDocument: "after" } for at få det opdaterede dokument returneret i stedet.
findOneAndReplace()
Ligesom findOneAndUpdate(), men denne metode erstatter hele dokumentet, ligesom replaceOne(). Den returnerer også enten det originale eller det erstattede dokument, afhængigt af de valgte optioner. Dette kan være nyttigt, hvis man skal arkivere den gamle version af et dokument, før den overskrives.
Vigtige opdateringsoperatorer
For at kunne opdatere dokumenter effektivt, er det afgørende at kende de forskellige operatorer. $set er den mest almindelige, men der er mange andre nyttige operatorer.

| Operator | Beskrivelse | Eksempel |
|---|---|---|
$set | Sætter værdien af et felt. Hvis feltet ikke eksisterer, oprettes det. | { $set: { adresse: "Ny Adresse" } } |
$unset | Fjerner et specifikt felt fra et dokument. | { $unset: { status: "" } } |
$inc | Forøger (eller formindsker, med negativ værdi) værdien af et numerisk felt. | { $inc: { alder: 1 } } |
$rename | Omdøber et felt. | { $rename: { "studienr": "studenternummer" } } |
$push | Tilføjer et element til et array. | { $push: { kurser: "Matematik" } } |
$pull | Fjerner alle forekomster af en specifik værdi fra et array. | { $pull: { kurser: "Fysik" } } |
Upsert: Opdatering eller indsættelse
En meget kraftfuld feature i MongoDB's opdateringsmetoder er upsert. Når denne option sættes til true, vil operationen opføre sig som følger: Hvis et dokument, der matcher filteret, findes, bliver det opdateret. Hvis *intet* dokument matcher filteret, vil MongoDB oprette et nyt dokument baseret på en kombination af filter- og opdateringsdokumenterne.
Forestil dig, at vi vil opdatere en studerende med studie_id 9999, men vi er ikke sikre på, om vedkommende allerede eksisterer i databasen.
db.studerende.updateOne( { "studie_id": 9999 }, { $set: { navn: "Ny Studerende", alder: 20 } }, { upsert: true } );Hvis der ikke findes en studerende med studie_id 9999, vil denne kommando oprette et nyt dokument, der ser sådan ud: { "studie_id": 9999, "navn": "Ny Studerende", "alder": 20 }. Dette er ekstremt nyttigt for at undgå "find-then-insert" logik i applikationskoden.
Ofte Stillede Spørgsmål (FAQ)
Hvad er forskellen på updateOne() og findOneAndUpdate()?
updateOne() udfører kun opdateringen og returnerer en status (matchedCount, modifiedCount). findOneAndUpdate() udfører også opdateringen, men den returnerer selve dokumentet, enten før eller efter ændringen. Brug findOneAndUpdate(), når du har brug for at arbejde videre med dataene fra det opdaterede dokument i din applikation.
Hvornår skal jeg bruge $set i stedet for replaceOne()?
Brug næsten altid $set. $set er til at modificere et eller flere specifikke felter i et dokument uden at røre resten. Brug kun replaceOne() i de sjældne tilfælde, hvor du bevidst vil slette hele det eksisterende dokument (undtagen _id) og erstatte det med et helt nyt sæt felter.
Hvordan fjerner jeg et felt fra et dokument?
Brug $unset-operatoren. For eksempel vil db.studerende.updateOne({ navn: "Peter Jensen" }, { $unset: { adresse: "" } }) fjerne adressefeltet fra Peter Jensens dokument. Værdien tildelt til feltet i $unset-dokumentet (her en tom streng) har ingen betydning.
Hvad sker der, hvis mit updateMany()-filter ikke matcher nogen dokumenter?
Der sker ingenting. Operationen vil blot returnere matchedCount: 0 og modifiedCount: 0. Ingen fejl vil blive kastet, og ingen data vil blive ændret. Det er en sikker operation.
Hvis du vil læse andre artikler, der ligner Guide: Sådan opdaterer du felter i MongoDB, kan du besøge kategorien Sundhed.
