I MongoDB, $mergeObjects
aggregeringspipeline-operatör kombinerar flera dokument till ett enda dokument.
Syntax
$mergeObjects
operatorn stöder två syntaxer.
Syntax 1:
{ $mergeObjects: [ <document1>, <document2>, ... ] }
Syntax 2:
{ $mergeObjects: <document> }
Den första syntaxen accepterar flera argument och den andra syntaxen accepterar ett argument.
Exempel på syntax 1 (flera argument)
Den första syntaxen innebär att tillhandahålla $mergeObjects
med mer än ett argument/dokument. $mergeObjects
kombinerar sedan dessa dokument till ett.
Anta att vi har en samling som heter users
med följande dokument:
{ "_id" : 1, "name" : { "f_name" : "Homer", "l_name" : "Simpson" }, "contact" : { "email" : "[email protected]", "ph" : null } }
Vi kan använda $mergeObjects
för att slå samman name
och contact
fält:
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 det här fallet slog vi ihop båda fälten till ett enda fält som heter user
. Om vi hade fler fält/dokument hade vi kunnat slå ihop dessa också om vi ville.
Duplicera fältnamn
Om dokumenten som ska sammanfogas innehåller dubbletter av fältnamn, $mergeObjects
skriver över fältet när det slår samman dokumenten. Därför innehåller fältet i det resulterande dokumentet värdet från det senast sammanslagna dokumentet för det fältet.
Anta att vi har följande dokument:
{ "_id" : 2, "name" : { "f_name" : "Peter", "l_name" : "Griffin" }, "contact" : { "email" : "[email protected]", "f_name" : "Bart" } }
Vi kan se att båda dokumenten innehåller ett fält som heter f_name
.
Så här händer när vi slår samman dessa dokument:
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
fältet i det resulterande dokumentet innehåller Bart
, vilket är värdet från det senaste dokumentet som slogs samman.
Nullvärden
Om du slår samman ett dokument med null
, kommer det resulterande dokumentet att returneras utan några ändringar.
Men om alla dokument som ska slås samman är null
, sedan returneras ett tomt dokument.
Anta att vi har följande dokument:
{ "_id" : 3, "name" : { "f_name" : "Hubert", "l_name" : "Farnsworth" }, "contact" : null } { "_id" : 4, "name" : null, "contact" : null }
Här är vad som händer när vi slår samman name
och contact
fält i dessa två dokument:
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" : { } }
Exempel på syntax 2 (enkelt argument)
Här är två exempel som använder syntaxen för det enda argumentet.
$group
Stage Accumulator
I det första exemplet, $mergeObjects
används som en $group
stegackumulator.
Anta att vi har en samling som heter products
med följande dokument:
{ "_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 gruppera dessa dokument efter deras product
och använd sedan $mergeObjects
för att slå samman inventory
fält för varje grupp:
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 } }
Arrayer
Det här exemplet gäller $mergeObjects
till ett enda dokument som innehåller ett fält med en mängd dokument.
Anta att vi har en samling som heter test
med följande dokument:
{ "_id" : 1, "data" : [ { "a" : 1, "b" : 2 }, { "c" : 3, "d" : 4 } ] }
Vi kan använda $mergeObjects
till data
fält:
db.test.aggregate(
[
{
$project:
{
result: { $mergeObjects: "$data" }
}
}
]
)
Resultat:
{ "_id" : 1, "result" : { "a" : 1, "b" : 2, "c" : 3, "d" : 4 } }
Fält saknas
$mergeObjects
ignorerar eventuella saknade fält. Det vill säga, om du anger ett fält som inte finns ignorerar det det. Om inget av fälten finns, returnerar det ett tomt dokument.
Exempel:
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 här är vad som händer när ingen av fälten finns:
db.users.aggregate(
[
{
$project:
{
user: { $mergeObjects: [ "$wrong", "$oops" ] }
}
}
]
).pretty()
Resultat:
{ "_id" : 1, "user" : { } } { "_id" : 2, "user" : { } } { "_id" : 3, "user" : { } } { "_id" : 4, "user" : { } }
Resultatet är ett tomt dokument.
Det är samma sak när du använder syntaxen med ett argument.
Exempel:
db.products.aggregate( [
{ $group: {
_id: "$product",
mergedProducts: { $mergeObjects: "$oops!" }
}
}
]).pretty()
Resultat:
{ "_id" : "Shorts", "mergedProducts" : { } } { "_id" : "Shirt", "mergedProducts" : { } }