sql >> Database >  >> NoSQL >> MongoDB

MongoDB $push versus $addToSet:wat is het verschil?

MongoDB heeft een $push operator en een $addToSet operator, die beide ongeveer hetzelfde doen.

Beide operators voegen waarden toe aan een bestaande array. Het belangrijkste verschil is hoe ze omgaan met arrays die al de waarde bevatten die u probeert toe te voegen, en ook in de modifiers die kunnen worden gebruikt.

De verschillen

Bestaande waarden Als de waarde al in de array bestaat, $push zal de waarde nog steeds toevoegen (resulterend in dubbele waarden).
Echter, $addToSet voegt de waarde alleen toe als deze nog niet in de array bestaat. Daarom, als de waarde al bestaat, $addToSet zal het niet toevoegen (het zal niets doen).
Modificaties De $push operator kan worden gebruikt met extra modificaties, zoals $sort , $slice , en $position , terwijl $addToSet kan niet (tenminste, niet vanaf MongoDB 4.4).

Bestaande waarden

Stel we hebben een collectie met de volgende documenten:

db.players.find()

Resultaat:

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

Laten we $addToSet gebruiken om te proberen een waarde aan een van de arrays toe te voegen.

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

Uitgang:

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

Dit vertelt ons dat er een overeenkomend document was (document 3), maar dat het niet is gewijzigd. Het is niet gewijzigd omdat de waarde die we probeerden in te voegen (5 ) bestaat al in de array.

Laten we eens in de collectie kijken:

db.players.find()

Resultaat:

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

Zoals verwacht is document 3 niet gewijzigd.

Laten we $push proberen in plaats daarvan:

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

Uitgang:

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

Deze keer zien we dat het document is gewijzigd.

We kunnen dit verifiëren door de collectie opnieuw te controleren:

db.products.find()

Resultaat:

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

Modificaties

De $push operator kan worden gebruikt met modifiers zoals $position , $sort , en $slice .

De $addToSet operator kan niet worden gebruikt met deze modifiers.

Dit is wat er gebeurt als ik deze modifiers probeer te gebruiken met $addToSet :

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

Uitgang:

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

De foutmelding vertelt ons dat de $position , $sort , en $slice zijn onverwachte velden (d.w.z. ze zouden er niet moeten zijn).

Laten we dezelfde modifiers proberen met $push :

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

Uitgang:

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

Deze keer werkte het zonder fouten.

Controleer het resultaat:

db.players.find()

Resultaat:

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

We kunnen zien dat de waarde is toegevoegd. Ook al hebben we $position: 0 specified gespecificeerd , we hebben ook $sort: 1 . opgegeven , wat betekent dat de array is gesorteerd nadat we deze hebben gepositioneerd.

We hebben ook $slice: 5 . gespecificeerd , die de array beperkte tot slechts 5 elementen (wat uiteindelijk precies het aantal elementen in de array was).


  1. Importeer meer dan 1 json-bestand met mongoimport

  2. Hoe Redis draaiend te krijgen op Azure?

  3. HBase-voorbeeldtabel

  4. Verbinding geweigerd voor Redis op Heroku