sql >> Database teknologi >  >> NoSQL >> MongoDB

MongoDB findAndModify()

I MongoDB er db.collection.findAndModify() metoden ændrer og returnerer et enkelt dokument.

collection del er navnet på den samling, som operationen skal udføres med.

Eksempel

Antag, at vi har en samling kaldet pets der indeholder følgende dokumenter:

{ "_id" : 1, "name" : "Wag", "type" : "Dog" }
{ "_id" : 2, "name" : "Bark", "type" : "Dog" }
{ "_id" : 3, "name" : "Meow", "type" : "Cat" }

Vi kan bruge db.collection.findAndModify() metode til at ændre et af disse dokumenter.

db.pets.findAndModify({
    query: { type: "Dog" },
    update: { type: "Cow" }
})

Resultat:

{ "_id" : 1, "name" : "Wag", "type" : "Dog" } 

Som standard returnerer den det originale dokument (ikke den ændrede version).

Bemærk, at kun én hund blev opdateret, selvom der er to hunde i samlingen.

Lad os tjekke samlingen.

db.pets.find()

Resultat:

{ "_id" : 1, "type" : "Cow" }
{ "_id" : 2, "name" : "Bark", "type" : "Dog" }
{ "_id" : 3, "name" : "Meow", "type" : "Cat" }

Vi kan se, at det første dokument nu indeholder en ko i stedet for en hund. Vi kan dog også se, at dokumentets navnefelt er forsvundet.

Det er fordi, når du sender et dokument til update argument, db.collection.findAndModify() udfører en udskiftning.

Brug af en opdateringsoperatør

Hvis vi ville opdatere et felt, men lade resten af ​​dokumentet være intakt, skulle vi inkludere det/de relevante opdateringsoperatørudtryk i vores dokument.

Med samlingen i dens nuværende tilstand, lad os udføre endnu en findAndModify() operation mod det, men denne gang bruger vi $set opdateringsoperatør for at indstille det felt, vi ønsker ændret.

db.pets.findAndModify({
    query: { type: "Dog" },
    update: { $set: { type: "Horse" } }
})

Resultat:

{ "_id" : 2, "name" : "Bark", "type" : "Dog" }

Denne gang blev den resterende hund opdateret.

Lad os tage et kig på samlingen.

db.pets.find()

Resultat:

{ "_id" : 1, "type" : "Cow" }
{ "_id" : 2, "name" : "Bark", "type" : "Horse" }
{ "_id" : 3, "name" : "Meow", "type" : "Cat" }

Denne gang blev det relevante felt opdateret, og resten af ​​dokumentet forblev intakt.

Returner det ændrede dokument

Som standard returneres det originale dokument, når du bruger db.collection.findAndModify() .

Hvis du foretrækker at få det ændrede dokument returneret i stedet, skal du bruge new parameter.

Som standard er dette new: false , hvilket resulterer i, at det originale dokument returneres. Men ved at angive new: true resulterer i, at det ændrede dokument returneres i stedet.

Lad os lave en anden ændring, men denne gang bruger vi new: true .

db.pets.findAndModify({
    query: { name: "Meow" },
    update: { $set: { name: "Scratch" } },
    new: true
})

Resultat:

{ "_id" : 3, "name" : "Scratch", "type" : "Cat" }

Så vi omdøbte Meow til Scratch og outputtet afspejler vores ændringer.

Upserts

Du kan udføre upserts ved at angive upsert: true .

En upsert er en mulighed, som du kan bruge til opdateringshandlinger. Hvis det angivne dokument ikke eksisterer, indsættes et nyt. Hvis det gør eksisterer, så opdateres det originale dokument (og intet dokument er indsat).

Eksempel med upsert: false

Her er et eksempel på forsøg på at opdatere et ikke-eksisterende dokument, når upsert: false .

db.pets.findAndModify({
    query: { _id: 4 },
    update: { _id: 4, name: "Fetch", type: "Dog" },
    new: true
})

Resultat:

null

Dokumentet eksisterede ikke i samlingen og derfor findAndModify() returnerede null . Selvom vi ikke specificerede upsert: false , vi ved, at det var falsk, fordi det er standardværdien (dvs. det er den værdi, der bruges, når du ikke angiver en upsert-indstilling).

Hvis vi kigger igen i samlingen, kan vi se, at dokumentet ikke blev slettet.

db.pets.find()

Resultat:

{ "_id" : 1, "type" : "Cow" }
{ "_id" : 2, "name" : "Bark", "type" : "Horse" }
{ "_id" : 3, "name" : "Scratch", "type" : "Cat" }

Eksempel med upsert: true

Nu er den her igen, men denne gang angiver vi upsert: true .

db.pets.findAndModify({
    query: { _id: 4 },
    update: { _id: 4, name: "Fetch", type: "Dog" },
    new: true,
    upsert: true
})

Resultat:

{ "_id" : 4, "name" : "Fetch", "type" : "Dog" }

Denne gang er et nyt dokument opsat, og vi ser det omdannede dokument som output (fordi vi har angivet new: true ).

Lad os tjekke samlingen igen.

db.pets.find()

Resultat:

{ "_id" : 1, "type" : "Cow" }
{ "_id" : 2, "name" : "Bark", "type" : "Horse" }
{ "_id" : 3, "name" : "Scratch", "type" : "Cat" }
{ "_id" : 4, "name" : "Fetch", "type" : "Dog" }

Så vi kan se, at det nye dokument faktisk blev ophævet.

ArrayFilters-parameteren

Når du arbejder med arrays, kan du bruge arrayFilters parameter sammen med den positionelle $ operatør for at bestemme, hvilke array-elementer der skal opdateres. Dette giver dig mulighed for at opdatere et array-element baseret på dets værdi, selvom du ikke kender dets position.

Antag for eksempel, at vi har en samling kaldet players med følgende dokumenter:

{ "_id" : 1, "scores" : [ 1, 5, 3 ] }
{ "_id" : 2, "scores" : [ 8, 17, 18 ] }
{ "_id" : 3, "scores" : [ 15, 11, 8 ] }

Vi kunne køre følgende forespørgsel for kun at opdatere de array-elementer, der har en værdi højere end et bestemt beløb (i dette tilfælde 10).

db.players.findAndModify({
   query: { scores: { $gte: 10 } },
   update: { $set: { "scores.$[e]" : 10 } },
   arrayFilters: [ { "e": { $gte: 10 } } ]
})

Resultat:

{ "_id" : 2, "scores" : [ 8, 17, 18 ] }

Som forventet opdaterer dette kun ét dokument, selvom to dokumenter matcher kriterierne.

Sådan ser dokumenterne ud nu.

db.players.find()

Resultat:

{ "_id" : 1, "scores" : [ 1, 5, 3 ] }
{ "_id" : 2, "scores" : [ 8, 10, 10 ] }
{ "_id" : 3, "scores" : [ 15, 11, 8 ] }

Dokument 2 havde to array-elementer opdateret, fordi disse elementer matchede kriterierne.

Flere oplysninger

db.collection.findAndModify() metode accepterer også andre parametre, såsom writeConcern , collation , bypassDocumentValidation og mere.

Se MongoDB-dokumentationen for db.collections.findAndModify() for mere information.


  1. Hvordan kan jeg få Webmachine og eredis til at arbejde sammen?

  2. Hvordan søger man i redis efter hash-nøgler?

  3. PyMongo-transaktionsfejl:Transaktionsnumre er kun tilladt på et replikasætmedlem eller mongoer

  4. Misbrug cURL til at kommunikere med Redis