MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

MongoDB $push vs $addToSet:Was ist der Unterschied?

MongoDB hat einen $push -Operator und ein $addToSet Betreiber, die beide eine sehr ähnliche Sache machen.

Beide Operatoren hängen Werte an ein vorhandenes Array an. Der Hauptunterschied besteht darin, wie sie mit Arrays umgehen, die bereits den Wert enthalten, den Sie anhängen möchten, und auch in den Modifikatoren, die verwendet werden können.

Die Unterschiede

Vorhandene Werte Wenn der Wert bereits im Array existiert, $push wird den Wert dennoch anhängen (was zu doppelten Werten führt).
Jedoch $addToSet hängt den Wert nur an, wenn er noch nicht im Array vorhanden ist. Wenn der Wert also bereits vorhanden ist, $addToSet wird es nicht anhängen (es wird nichts tun).
Modifikatoren Der $push -Operator kann mit zusätzlichen Modifikatoren wie $sort verwendet werden , $slice , und $position , wohingegen $addToSet kann nicht (zumindest nicht ab MongoDB 4.4).

Vorhandene Werte

Angenommen, wir haben eine Sammlung mit den folgenden Dokumenten:

db.players.find()

Ergebnis:

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

Lassen Sie uns $addToSet verwenden zu versuchen, einen Wert an eines der Arrays anzuhängen.

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

Ausgabe:

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

Dies sagt uns, dass es ein passendes Dokument (Dokument 3) gab, aber es wurde nicht geändert. Es wurde nicht geändert, weil der Wert, den wir einzufügen versuchten (5 ) existiert bereits im Array.

Sehen wir uns die Sammlung an:

db.players.find()

Ergebnis:

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

Wie erwartet wurde Dokument 3 nicht geändert.

Versuchen wir es mit $push stattdessen:

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

Ausgabe:

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

Dieses Mal sehen wir, dass das Dokument geändert wurde.

Wir können dies überprüfen, indem wir die Sammlung erneut überprüfen:

db.products.find()

Ergebnis:

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

Modifikatoren

Der $push Der Operator kann mit Modifikatoren wie $position verwendet werden , $sort , und $slice .

Das $addToSet Operator kann nicht mit diesen Modifikatoren verwendet werden.

Folgendes passiert, wenn ich versuche, diese Modifikatoren mit $addToSet zu verwenden :

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

Ausgabe:

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

Die Fehlermeldung sagt uns, dass die $position , $sort , und $slice sind unerwartete Felder (d. h. sie sollten nicht vorhanden sein).

Lassen Sie uns dieselben Modifikatoren mit $push ausprobieren :

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

Ausgabe:

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

Diesmal hat es ohne Fehler funktioniert.

Überprüfen Sie das Ergebnis:

db.players.find()

Ergebnis:

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

Wir können sehen, dass der Wert angehängt wurde. Obwohl wir $position: 0 angegeben haben haben wir auch $sort: 1 angegeben , was bedeutet, dass das Array sortiert wurde, nachdem wir es positioniert hatten.

Wir haben auch $slice: 5 angegeben , wodurch das Array auf nur 5 Elemente beschränkt wurde (was, wie sich herausstellte, sowieso genau so viele Elemente im Array waren).