В MongoDB, $mergeObjects Операторът на тръбопровода за агрегиране комбинира множество документи в един документ.
Синтаксис
$mergeObjects операторът поддържа два синтаксиса.
Синтаксис 1:
{ $mergeObjects: [ <document1>, <document2>, ... ] } Синтаксис 2:
{ $mergeObjects: <document> } Първият синтаксис приема множество аргументи, а вторият синтаксис приема един аргумент.
Пример за синтаксис 1 (множество аргументи)
Първият синтаксис включва предоставяне на $mergeObjects с повече от един аргумент/документ. $mergeObjects след това комбинира тези документи в един.
Да предположим, че имаме колекция, наречена users със следния документ:
{
"_id" : 1,
"name" : {
"f_name" : "Homer",
"l_name" : "Simpson"
},
"contact" : {
"email" : "example@sqldat.com",
"ph" : null
}
}
Можем да използваме $mergeObjects за да обедините name и contact полета:
db.users.aggregate(
[
{
$project:
{
user: { $mergeObjects: [ "$name", "$contact" ] }
}
}
]
).pretty() Резултат:
{
"_id" : 1,
"user" : {
"f_name" : "Homer",
"l_name" : "Simpson",
"email" : "example@sqldat.com",
"ph" : null
}
}
В този случай обединихме двете полета в едно поле, наречено user . Ако имахме повече полета/документи, бихме могли да обединим и тях, ако искахме.
Дублиращи се имена на полета
Ако документите, които ще бъдат обединени, съдържат дублиращи се имена на полета, $mergeObjects презаписва полето, докато обединява документите. Следователно полето в получения документ съдържа стойността от последния документ, обединен за това поле.
Да предположим, че имаме следния документ:
{
"_id" : 2,
"name" : {
"f_name" : "Peter",
"l_name" : "Griffin"
},
"contact" : {
"email" : "example@sqldat.com",
"f_name" : "Bart"
}
}
Можем да видим, че и двата документа съдържат поле с име f_name .
Ето какво се случва, когато обединим тези документи:
db.users.aggregate(
[
{ $match: { _id: 2 } },
{
$project:
{
user: { $mergeObjects: [ "$name", "$contact" ] }
}
}
]
).pretty() Резултат:
{
"_id" : 2,
"user" : {
"f_name" : "Bart",
"l_name" : "Griffin",
"email" : "example@sqldat.com"
}
}
f_name полето в получения документ съдържа Bart , което е стойността от последния документ, който е бил обединен.
Нулеви стойности
Ако обединявате документ с null , полученият документ ще бъде върнат без никакви промени.
Но ако всички документи за сливане са null , след което се връща празен документ.
Да предположим, че имаме следните документи:
{
"_id" : 3,
"name" : {
"f_name" : "Hubert",
"l_name" : "Farnsworth"
},
"contact" : null
}
{ "_id" : 4, "name" : null, "contact" : null }
Ето какво се случва, когато обединим name и contact полета в тези два документа:
db.users.aggregate(
[
{ $match: { _id: { $in: [ 3, 4 ] } } },
{
$project:
{
user: { $mergeObjects: [ "$name", "$contact" ] }
}
}
]
) Резултат:
{ "_id" : 3, "user" : { "f_name" : "Hubert", "l_name" : "Farnsworth" } }
{ "_id" : 4, "user" : { } } Примери за синтаксис 2 (единичен аргумент)
Ето два примера, които използват синтаксиса на единичния аргумент.
$group Сценичен акумулатор
В първия пример $mergeObjects се използва като $group сценичен акумулатор.
Да предположим, че имаме колекция, наречена products със следните документи:
{
"_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
}
}
Можем да групираме тези документи по техния product поле и след това използвайте $mergeObjects за да обедините inventory поле за всяка група:
db.products.aggregate( [
{ $group: {
_id: "$product",
mergedProducts: { $mergeObjects: "$inventory" }
}
}
]).pretty() Резултат:
{
"_id" : "Shorts",
"mergedProducts" : {
"blue" : 2,
"red" : 8,
"green" : 5,
"black" : 3
}
}
{
"_id" : "Shirt",
"mergedProducts" : {
"blue" : 10,
"red" : 2,
"green" : 3,
"black" : 1
}
} Масиви
Този пример се прилага $mergeObjects към един документ, който съдържа поле с масив от документи.
Да предположим, че имаме колекция, наречена test със следните документи:
{
"_id" : 1,
"data" : [
{
"a" : 1,
"b" : 2
},
{
"c" : 3,
"d" : 4
}
]
}
Можем да приложим $mergeObjects към data поле:
db.test.aggregate(
[
{
$project:
{
result: { $mergeObjects: "$data" }
}
}
]
) Резултат:
{ "_id" : 1, "result" : { "a" : 1, "b" : 2, "c" : 3, "d" : 4 } } Липсващи полета
$mergeObjects игнорира всички липсващи полета. Тоест, ако предоставите поле, което не съществува, то го игнорира. Ако нито едно от полетата не съществува, то връща празен документ.
Пример:
db.users.aggregate(
[
{
$project:
{
user: { $mergeObjects: [ "$name", "$oops" ] }
}
}
]
).pretty() Резултат:
{ "_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" : { } } Но ето какво се случва, когато няма от полетата съществуват:
db.users.aggregate(
[
{
$project:
{
user: { $mergeObjects: [ "$wrong", "$oops" ] }
}
}
]
).pretty() Резултат:
{ "_id" : 1, "user" : { } }
{ "_id" : 2, "user" : { } }
{ "_id" : 3, "user" : { } }
{ "_id" : 4, "user" : { } } Резултатът е празен документ.
Същото е и при използване на синтаксис с един аргумент.
Пример:
db.products.aggregate( [
{ $group: {
_id: "$product",
mergedProducts: { $mergeObjects: "$oops!" }
}
}
]).pretty() Резултат:
{ "_id" : "Shorts", "mergedProducts" : { } }
{ "_id" : "Shirt", "mergedProducts" : { } }