I MongoDB er $mergeObjects
aggregeringspipeline-operatør kombinerer flere dokumenter til et enkelt dokument.
Syntaks
$mergeObjects
operatoren understøtter to syntakser.
Syntaks 1:
{ $mergeObjects: [ <document1>, <document2>, ... ] }
Syntaks 2:
{ $mergeObjects: <document> }
Den første syntaks accepterer flere argumenter, og den anden syntaks accepterer ét argument.
Eksempel på syntaks 1 (flere argumenter)
Den første syntaks involverer at give $mergeObjects
med mere end ét argument/dokument. $mergeObjects
kombinerer derefter disse dokumenter til ét.
Antag, at vi har en samling kaldet users
med følgende dokument:
{ "_id" : 1, "name" : { "f_name" : "Homer", "l_name" : "Simpson" }, "contact" : { "email" : "[email protected]", "ph" : null } }
Vi kan bruge $mergeObjects
for at flette name
og contact
felter:
db.users.aggregate(
[
{
$project:
{
user: { $mergeObjects: [ "$name", "$contact" ] }
}
}
]
).pretty()
Resultat:
{ "_id" : 1, "user" : { "f_name" : "Homer", "l_name" : "Simpson", "email" : "[email protected]", "ph" : null } }
I dette tilfælde slog vi begge felter sammen til et enkelt felt kaldet user
. Hvis vi havde flere felter/dokumenter, kunne vi også have slået dem sammen, hvis vi ville.
Dublerede feltnavne
Hvis dokumenterne, der skal flettes, indeholder duplikerede feltnavne, $mergeObjects
overskriver feltet, efterhånden som dokumenterne flettes. Derfor indeholder feltet i det resulterende dokument værdien fra det sidst flettede dokument for det pågældende felt.
Antag, at vi har følgende dokument:
{ "_id" : 2, "name" : { "f_name" : "Peter", "l_name" : "Griffin" }, "contact" : { "email" : "[email protected]", "f_name" : "Bart" } }
Vi kan se, at begge dokumenter indeholder et felt med navnet f_name
.
Her er, hvad der sker, når vi slår disse dokumenter sammen:
db.users.aggregate(
[
{ $match: { _id: 2 } },
{
$project:
{
user: { $mergeObjects: [ "$name", "$contact" ] }
}
}
]
).pretty()
Resultat:
{ "_id" : 2, "user" : { "f_name" : "Bart", "l_name" : "Griffin", "email" : "[email protected]" } }
f_name
feltet i det resulterende dokument indeholder Bart
, som er værdien fra det sidste dokument, der blev flettet.
Nul-værdier
Hvis et dokument flettes med null
, vil det resulterende dokument blive returneret uden ændringer.
Men hvis alle dokumenter, der skal flettes, er null
, så returneres et tomt dokument.
Antag, at vi har følgende dokumenter:
{ "_id" : 3, "name" : { "f_name" : "Hubert", "l_name" : "Farnsworth" }, "contact" : null } { "_id" : 4, "name" : null, "contact" : null }
Her er, hvad der sker, når vi slår name
sammen og contact
felter i disse to dokumenter:
db.users.aggregate(
[
{ $match: { _id: { $in: [ 3, 4 ] } } },
{
$project:
{
user: { $mergeObjects: [ "$name", "$contact" ] }
}
}
]
)
Resultat:
{ "_id" : 3, "user" : { "f_name" : "Hubert", "l_name" : "Farnsworth" } } { "_id" : 4, "user" : { } }
Eksempler på syntaks 2 (enkelt argument)
Her er to eksempler, der bruger syntaksen for det enkelte argument.
$group
Stage Akkumulator
I det første eksempel, $mergeObjects
bruges som en $group
sceneakkumulator.
Antag, at vi har en samling kaldet products
med følgende dokumenter:
{ "_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 } }
Vi kan gruppere disse dokumenter efter deres product
felt, og brug derefter $mergeObjects
for at flette inventory
felt for hver gruppe:
db.products.aggregate( [
{ $group: {
_id: "$product",
mergedProducts: { $mergeObjects: "$inventory" }
}
}
]).pretty()
Resultat:
{ "_id" : "Shorts", "mergedProducts" : { "blue" : 2, "red" : 8, "green" : 5, "black" : 3 } } { "_id" : "Shirt", "mergedProducts" : { "blue" : 10, "red" : 2, "green" : 3, "black" : 1 } }
Arrays
Dette eksempel gælder $mergeObjects
til et enkelt dokument, der indeholder et felt med en række dokumenter.
Antag, at vi har en samling kaldet test
med følgende dokumenter:
{ "_id" : 1, "data" : [ { "a" : 1, "b" : 2 }, { "c" : 3, "d" : 4 } ] }
Vi kan anvende $mergeObjects
til data
felt:
db.test.aggregate(
[
{
$project:
{
result: { $mergeObjects: "$data" }
}
}
]
)
Resultat:
{ "_id" : 1, "result" : { "a" : 1, "b" : 2, "c" : 3, "d" : 4 } }
Manglende felter
$mergeObjects
ignorerer eventuelle manglende felter. Det vil sige, at hvis du angiver et felt, der ikke eksisterer, ignorerer det det. Hvis ingen af felterne eksisterer, returnerer det et tomt dokument.
Eksempel:
db.users.aggregate(
[
{
$project:
{
user: { $mergeObjects: [ "$name", "$oops" ] }
}
}
]
).pretty()
Resultat:
{ "_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" : { } }
Men her er, hvad der sker, når ingen af felterne findes:
db.users.aggregate(
[
{
$project:
{
user: { $mergeObjects: [ "$wrong", "$oops" ] }
}
}
]
).pretty()
Resultat:
{ "_id" : 1, "user" : { } } { "_id" : 2, "user" : { } } { "_id" : 3, "user" : { } } { "_id" : 4, "user" : { } }
Resultatet er et tomt dokument.
Det er det samme, når du bruger enkelt-argument-syntaksen.
Eksempel:
db.products.aggregate( [
{ $group: {
_id: "$product",
mergedProducts: { $mergeObjects: "$oops!" }
}
}
]).pretty()
Resultat:
{ "_id" : "Shorts", "mergedProducts" : { } } { "_id" : "Shirt", "mergedProducts" : { } }