In MongoDB, de $mergeObjects
aggregatiepijplijnoperator combineert meerdere documenten in één document.
Syntaxis
De $mergeObjects
operator ondersteunt twee syntaxis.
Syntaxis 1:
{ $mergeObjects: [ <document1>, <document2>, ... ] }
Syntaxis 2:
{ $mergeObjects: <document> }
De eerste syntaxis accepteert meerdere argumenten en de tweede syntaxis accepteert één argument.
Voorbeeld van syntaxis 1 (meerdere argumenten)
De eerste syntaxis omvat het verstrekken van $mergeObjects
met meer dan één argument/document. $mergeObjects
combineert die documenten vervolgens tot één.
Stel dat we een verzameling hebben met de naam users
met het volgende document:
{ "_id" : 1, "name" : { "f_name" : "Homer", "l_name" : "Simpson" }, "contact" : { "email" : "[email protected]", "ph" : null } }
We kunnen $mergeObjects
. gebruiken om de name
samen te voegen en contact
velden:
db.users.aggregate(
[
{
$project:
{
user: { $mergeObjects: [ "$name", "$contact" ] }
}
}
]
).pretty()
Resultaat:
{ "_id" : 1, "user" : { "f_name" : "Homer", "l_name" : "Simpson", "email" : "[email protected]", "ph" : null } }
In dit geval hebben we beide velden samengevoegd tot een enkel veld met de naam user
. Als we meer velden/documenten hadden, hadden we die ook kunnen samenvoegen als we dat hadden gewild.
Dubbele veldnamen
Als de samen te voegen documenten dubbele veldnamen bevatten, $mergeObjects
overschrijft het veld terwijl het de documenten samenvoegt. Daarom bevat het veld in het resulterende document de waarde van het laatste document dat voor dat veld is samengevoegd.
Stel dat we het volgende document hebben:
{ "_id" : 2, "name" : { "f_name" : "Peter", "l_name" : "Griffin" }, "contact" : { "email" : "[email protected]", "f_name" : "Bart" } }
We kunnen zien dat beide documenten een veld bevatten met de naam f_name
.
Dit is wat er gebeurt als we die documenten samenvoegen:
db.users.aggregate(
[
{ $match: { _id: 2 } },
{
$project:
{
user: { $mergeObjects: [ "$name", "$contact" ] }
}
}
]
).pretty()
Resultaat:
{ "_id" : 2, "user" : { "f_name" : "Bart", "l_name" : "Griffin", "email" : "[email protected]" } }
De f_name
veld in het resulterende document bevat Bart
, wat de waarde is van het laatste document dat is samengevoegd.
Null-waarden
Als u een document samenvoegt met null
, wordt het resulterende document zonder enige wijzigingen geretourneerd.
Maar als alle samen te voegen documenten null
zijn , dan wordt een leeg document geretourneerd.
Stel dat we de volgende documenten hebben:
{ "_id" : 3, "name" : { "f_name" : "Hubert", "l_name" : "Farnsworth" }, "contact" : null } { "_id" : 4, "name" : null, "contact" : null }
Dit gebeurt er als we de name
samenvoegen en contact
velden in die twee documenten:
db.users.aggregate(
[
{ $match: { _id: { $in: [ 3, 4 ] } } },
{
$project:
{
user: { $mergeObjects: [ "$name", "$contact" ] }
}
}
]
)
Resultaat:
{ "_id" : 3, "user" : { "f_name" : "Hubert", "l_name" : "Farnsworth" } } { "_id" : 4, "user" : { } }
Voorbeelden van syntaxis 2 (enkel argument)
Hier zijn twee voorbeelden die de syntaxis van het enkele argument gebruiken.
$group
Stage Accumulator
In het eerste voorbeeld, $mergeObjects
wordt gebruikt als een $group
fase accumulator.
Stel dat we een verzameling hebben met de naam products
met de volgende documenten:
{ "_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 } }
We kunnen deze documenten groeperen op hun product
veld, en gebruik dan $mergeObjects
om de inventory
samen te voegen veld voor elke groep:
db.products.aggregate( [
{ $group: {
_id: "$product",
mergedProducts: { $mergeObjects: "$inventory" }
}
}
]).pretty()
Resultaat:
{ "_id" : "Shorts", "mergedProducts" : { "blue" : 2, "red" : 8, "green" : 5, "black" : 3 } } { "_id" : "Shirt", "mergedProducts" : { "blue" : 10, "red" : 2, "green" : 3, "black" : 1 } }
Arrays
Dit voorbeeld is van toepassing op $mergeObjects
naar een enkel document dat een veld met een reeks documenten bevat.
Stel dat we een verzameling hebben met de naam test
met de volgende documenten:
{ "_id" : 1, "data" : [ { "a" : 1, "b" : 2 }, { "c" : 3, "d" : 4 } ] }
We kunnen $mergeObjects
. toepassen naar de data
veld:
db.test.aggregate(
[
{
$project:
{
result: { $mergeObjects: "$data" }
}
}
]
)
Resultaat:
{ "_id" : 1, "result" : { "a" : 1, "b" : 2, "c" : 3, "d" : 4 } }
Ontbrekende velden
$mergeObjects
negeert eventuele ontbrekende velden. Dat wil zeggen, als u een veld opgeeft dat niet bestaat, wordt dit genegeerd. Als geen van de velden bestaat, wordt een leeg document geretourneerd.
Voorbeeld:
db.users.aggregate(
[
{
$project:
{
user: { $mergeObjects: [ "$name", "$oops" ] }
}
}
]
).pretty()
Resultaat:
{ "_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" : { } }
Dit is echter wat er gebeurt als geen van de velden bestaat:
db.users.aggregate(
[
{
$project:
{
user: { $mergeObjects: [ "$wrong", "$oops" ] }
}
}
]
).pretty()
Resultaat:
{ "_id" : 1, "user" : { } } { "_id" : 2, "user" : { } } { "_id" : 3, "user" : { } } { "_id" : 4, "user" : { } }
Het resultaat is een leeg document.
Het is hetzelfde als de syntaxis met één argument wordt gebruikt.
Voorbeeld:
db.products.aggregate( [
{ $group: {
_id: "$product",
mergedProducts: { $mergeObjects: "$oops!" }
}
}
]).pretty()
Resultaat:
{ "_id" : "Shorts", "mergedProducts" : { } } { "_id" : "Shirt", "mergedProducts" : { } }