In MongoDB sind die $mergeObjects
Aggregation Pipeline Operator kombiniert mehrere Dokumente zu einem einzigen Dokument.
Syntax
Die $mergeObjects
Operator unterstützt zwei Syntaxen.
Syntax 1:
{ $mergeObjects: [ <document1>, <document2>, ... ] }
Syntax 2:
{ $mergeObjects: <document> }
Die erste Syntax akzeptiert mehrere Argumente und die zweite Syntax akzeptiert ein Argument.
Beispiel für Syntax 1 (mehrere Argumente)
Die erste Syntax beinhaltet die Bereitstellung von $mergeObjects
mit mehr als einem Argument/Dokument. $mergeObjects
kombiniert dann diese Dokumente zu einem.
Angenommen, wir haben eine Sammlung namens users
mit folgendem Dokument:
{ "_id" : 1, "name" : { "f_name" : "Homer", "l_name" : "Simpson" }, "contact" : { "email" : "[email protected]", "ph" : null } }
Wir können $mergeObjects
verwenden um den name
zusammenzuführen und contact
Felder:
db.users.aggregate(
[
{
$project:
{
user: { $mergeObjects: [ "$name", "$contact" ] }
}
}
]
).pretty()
Ergebnis:
{ "_id" : 1, "user" : { "f_name" : "Homer", "l_name" : "Simpson", "email" : "[email protected]", "ph" : null } }
In diesem Fall haben wir beide Felder zu einem einzigen Feld namens user
zusammengeführt . Wenn wir mehr Felder/Dokumente hätten, hätten wir diese auch zusammenführen können, wenn wir wollten.
Doppelte Feldnamen
Wenn die zusammenzuführenden Dokumente doppelte Feldnamen enthalten, wird $mergeObjects
überschreibt das Feld beim Zusammenführen der Dokumente. Daher enthält das Feld im resultierenden Dokument den Wert aus dem letzten Dokument, das für dieses Feld zusammengeführt wurde.
Angenommen, wir haben das folgende Dokument:
{ "_id" : 2, "name" : { "f_name" : "Peter", "l_name" : "Griffin" }, "contact" : { "email" : "[email protected]", "f_name" : "Bart" } }
Wir können sehen, dass beide Dokumente ein Feld namens f_name
enthalten .
Folgendes passiert, wenn wir diese Dokumente zusammenführen:
db.users.aggregate(
[
{ $match: { _id: 2 } },
{
$project:
{
user: { $mergeObjects: [ "$name", "$contact" ] }
}
}
]
).pretty()
Ergebnis:
{ "_id" : 2, "user" : { "f_name" : "Bart", "l_name" : "Griffin", "email" : "[email protected]" } }
Der f_name
Feld im resultierenden Dokument enthält Bart
, das ist der Wert aus dem zuletzt zusammengeführten Dokument.
Nullwerte
Beim Zusammenführen eines Dokuments mit null
, wird das resultierende Dokument ohne Änderungen zurückgegeben.
Aber wenn alle zusammenzuführenden Dokumente null
sind , dann wird ein leeres Dokument zurückgegeben.
Angenommen, wir haben die folgenden Dokumente:
{ "_id" : 3, "name" : { "f_name" : "Hubert", "l_name" : "Farnsworth" }, "contact" : null } { "_id" : 4, "name" : null, "contact" : null }
Folgendes passiert, wenn wir name
zusammenführen und contact
Felder in diesen beiden Dokumenten:
db.users.aggregate(
[
{ $match: { _id: { $in: [ 3, 4 ] } } },
{
$project:
{
user: { $mergeObjects: [ "$name", "$contact" ] }
}
}
]
)
Ergebnis:
{ "_id" : 3, "user" : { "f_name" : "Hubert", "l_name" : "Farnsworth" } } { "_id" : 4, "user" : { } }
Beispiele für Syntax 2 (Einzelargument)
Hier sind zwei Beispiele, die die Syntax mit einem einzigen Argument verwenden.
$group
Stufenakkumulator
Im ersten Beispiel $mergeObjects
wird als $group
verwendet Stufenakkumulator.
Angenommen, wir haben eine Sammlung namens products
mit folgenden Dokumenten:
{ "_id" : 1, "product" : "Shirt", "inventory" : { "blue" : 10, "red" : 2 } } { "_id" : 2, "product" : "Shirt", "inventory" : { "green" : 3, "black" : 1 } } { "_id" : 3, "product" : "Shorts", "inventory" : { "blue" : 2, "red" : 8 } } { "_id" : 4, "product" : "Shorts", "inventory" : { "green" : 5, "black" : 3 } }
Wir können diese Dokumente nach ihrem product
gruppieren Feld und verwenden Sie dann $mergeObjects
um das inventory
zusammenzuführen Feld für jede Gruppe:
db.products.aggregate( [
{ $group: {
_id: "$product",
mergedProducts: { $mergeObjects: "$inventory" }
}
}
]).pretty()
Ergebnis:
{ "_id" : "Shorts", "mergedProducts" : { "blue" : 2, "red" : 8, "green" : 5, "black" : 3 } } { "_id" : "Shirt", "mergedProducts" : { "blue" : 10, "red" : 2, "green" : 3, "black" : 1 } }
Arrays
Dieses Beispiel wendet $mergeObjects
an zu einem einzelnen Dokument, das ein Feld mit einem Array von Dokumenten enthält.
Angenommen, wir haben eine Sammlung namens test
mit folgenden Dokumenten:
{ "_id" : 1, "data" : [ { "a" : 1, "b" : 2 }, { "c" : 3, "d" : 4 } ] }
Wir können $mergeObjects
anwenden zu den data
Feld:
db.test.aggregate(
[
{
$project:
{
result: { $mergeObjects: "$data" }
}
}
]
)
Ergebnis:
{ "_id" : 1, "result" : { "a" : 1, "b" : 2, "c" : 3, "d" : 4 } }
Fehlende Felder
$mergeObjects
ignoriert alle fehlenden Felder. Das heißt, wenn Sie ein Feld angeben, das nicht vorhanden ist, wird es ignoriert. Wenn keines der Felder vorhanden ist, wird ein leeres Dokument zurückgegeben.
Beispiel:
db.users.aggregate(
[
{
$project:
{
user: { $mergeObjects: [ "$name", "$oops" ] }
}
}
]
).pretty()
Ergebnis:
{ "_id" : 1, "user" : { "f_name" : "Homer", "l_name" : "Simpson" } } { "_id" : 2, "user" : { "f_name" : "Peter", "l_name" : "Griffin" } } { "_id" : 3, "user" : { "f_name" : "Hubert", "l_name" : "Farnsworth" } } { "_id" : 4, "user" : { } }
Folgendes passiert jedoch, wenn keine der Felder existieren:
db.users.aggregate(
[
{
$project:
{
user: { $mergeObjects: [ "$wrong", "$oops" ] }
}
}
]
).pretty()
Ergebnis:
{ "_id" : 1, "user" : { } } { "_id" : 2, "user" : { } } { "_id" : 3, "user" : { } } { "_id" : 4, "user" : { } }
Das Ergebnis ist ein leeres Dokument.
Das Gleiche gilt für die Verwendung der Ein-Argument-Syntax.
Beispiel:
db.products.aggregate( [
{ $group: {
_id: "$product",
mergedProducts: { $mergeObjects: "$oops!" }
}
}
]).pretty()
Ergebnis:
{ "_id" : "Shorts", "mergedProducts" : { } } { "_id" : "Shirt", "mergedProducts" : { } }