sql >> Databasteknik >  >> NoSQL >> MongoDB

MongoDB $push vs $addToSet:Vad är skillnaden?

MongoDB har en $push operator och en $addToSet operatör, som båda gör en mycket liknande sak.

Båda operatorerna lägger till värden till en befintlig matris. Den största skillnaden ligger i hur de hanterar arrayer som redan innehåller värdet du försöker lägga till, och även i modifierarna som kan användas.

Skillnaderna

Befintliga värden Om värdet redan finns i arrayen, $push kommer fortfarande att lägga till värdet (vilket resulterar i dubbletter av värden).
Men $addToSet lägger bara till värdet om det inte redan finns i arrayen. Därför, om värdet redan finns, $addToSet kommer inte att lägga till det (det gör ingenting).
Modifierare $push operatorn kan användas med ytterligare modifierare, såsom $sort , $slice och $position , medan $addToSet kan inte (åtminstone inte från och med MongoDB 4.4).

Befintliga värden

Anta att vi har en samling med följande dokument:

db.players.find()

Resultat:

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

Låt oss använda $addToSet för att försöka lägga till ett värde till en av arrayerna.

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

Utdata:

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

Detta berättar för oss att det fanns ett matchande dokument (dokument 3), men det ändrades inte. Det ändrades inte eftersom värdet vi försökte infoga (5 ) finns redan i arrayen.

Låt oss titta 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 väntat har dokument 3 inte ändrats.

Låt oss prova $push istället:

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

Utdata:

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

Den här gången ser vi att dokumentet har ändrats.

Vi kan verifiera detta genom att kontrollera 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 ] }

Modifierare

$push operatorn kan användas med modifierare som $position , $sort och $slice .

$addToSet operatorn kan inte användas med dessa modifierare.

Här är vad som händer om jag försöker använda dessa modifierare med $addToSet :

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

Utdata:

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 }"
	}
})

Felmeddelandet talar om för oss att $position , $sort och $slice är oväntade fält (dvs. de borde inte finnas där).

Låt oss prova samma modifierare med $push :

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

Utdata:

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

Den här gången fungerade det felfritt.

Verifiera 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 att värdet har lagts till. Även om vi angav $position: 0 , vi angav också $sort: 1 , vilket betyder att arrayen sorterades efter att vi placerade den.

Vi angav också $slice: 5 , vilket begränsade arrayen till bara 5 element (vilket som det visade sig var exakt hur många element som fanns i arrayen ändå).


  1. Redis SCAN-matchning

  2. MongoDB - $set för att uppdatera eller push Array-element

  3. Hur man skapar användare och lägger till roll i MongoDB

  4. Redis Vs RabbitMQ som ett datamäklare/meddelandesystem mellan Logstash och elasticsearch