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).