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

MongoDB $push vs $addToSet:Hvad er forskellen?

MongoDB har en $push operator og en $addToSet operatør, som begge gør en meget lignende ting.

Begge operatorer tilføjer værdier til en eksisterende matrix. Den største forskel er i, hvordan de håndterer arrays, der allerede indeholder den værdi, du forsøger at tilføje, og også i de modifikatorer, der kan bruges.

Forskellene

Eksisterende værdier Hvis værdien allerede findes i arrayet, $push vil stadig tilføje værdien (hvilket resulterer i duplikerede værdier).
Dog $addToSet tilføjer kun værdien, hvis den ikke allerede findes i arrayet. Derfor, hvis værdien allerede eksisterer, $addToSet vil ikke tilføje det (det vil ikke gøre noget).
Modifiers $push operator kan bruges med yderligere modifikatorer, såsom $sort , $slice , og $position , hvorimod $addToSet kan ikke (i hvert fald ikke fra MongoDB 4.4).

Eksisterende værdier

Antag, at vi har en samling med følgende dokumenter:

db.players.find()

Resultat:

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

Lad os bruge $addToSet for at prøve at tilføje en værdi til et af arrays.

db.players.update(
   { _id: 3 },
   { $addToSet: { scores: 5 } }
)

Output:

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })

Dette fortæller os, at der var et matchende dokument (dokument 3), men det blev ikke ændret. Den blev ikke ændret, fordi den værdi, vi forsøgte at indsætte (5 ) findes allerede i arrayet.

Lad os se i samlingen:

db.players.find()

Resultat:

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

Som forventet er dokument 3 ikke blevet ændret.

Lad os prøve $push i stedet:

db.players.update(
   { _id: 3 },
   { $push: { scores: 5 } }
)

Output:

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

Denne gang ser vi, at dokumentet blev ændret.

Vi kan bekræfte dette ved at tjekke samlingen igen:

db.products.find()

Resultat:

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

Modifiers

$push operator kan bruges med modifikatorer såsom $position , $sort , og $slice .

$addToSet operator kan ikke bruges med disse modifikatorer.

Her er hvad der sker, hvis jeg prøver at bruge disse modifikatorer med $addToSet :

db.players.update(
   { _id: 3 },
   { 
     $addToSet: { 
        scores: {
           $each: [ 12 ],
           $position: 0,
           $sort: 1,
           $slice: 5
        }
      } 
    }
)

Output:

WriteResult({
	"nMatched" : 0,
	"nUpserted" : 0,
	"nModified" : 0,
	"writeError" : {
		"code" : 2,
		"errmsg" : "Found unexpected fields after $each in $addToSet: { $each: [ 12.0 ], $position: 0.0, $sort: 1.0, $slice: 5.0 }"
	}
})

Fejlmeddelelsen fortæller os, at $position , $sort , og $slice er uventede felter (dvs. de burde ikke være der).

Lad os prøve de samme modifikatorer med $push :

db.players.update(
   { _id: 3 },
   { 
     $push: { 
        scores: {
           $each: [ 12 ],
           $position: 0,
           $sort: 1,
           $slice: 5
        }
      } 
    }
)

Output:

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

Denne gang virkede det uden fejl.

Bekræft resultatet:

db.players.find()

Resultat:

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

Vi kan se, at værdien er blevet tilføjet. Selvom vi specificerede $position: 0 , vi specificerede også $sort: 1 , hvilket betyder, at arrayet blev sorteret efter vi havde placeret det.

Vi specificerede også $slice: 5 , som begrænsede arrayet til kun 5 elementer (hvilket som det viste sig, var præcis hvor mange elementer der var i arrayet alligevel).


  1. Find ud af, om en forespørgsel bruger et indeks i MongoDB

  2. Scriptet forsøgte at oprette en global variabel

  3. Hvordan laver jeg forespørgsler uden store og små bogstaver på Mongodb?

  4. Forøgelse af hundredvis af tællere på én gang, redis eller mongodb?