Trong MongoDB, $mergeObjects
nhà điều hành đường ống tổng hợp kết hợp nhiều tài liệu vào một tài liệu duy nhất.
Cú pháp
$mergeObjects
toán tử hỗ trợ hai cú pháp.
Cú pháp 1:
{ $mergeObjects: [ <document1>, <document2>, ... ] }
Cú pháp 2:
{ $mergeObjects: <document> }
Cú pháp đầu tiên chấp nhận nhiều đối số và cú pháp thứ hai chấp nhận một đối số.
Ví dụ về Cú pháp 1 (Nhiều Đối số)
Cú pháp đầu tiên liên quan đến việc cung cấp $mergeObjects
với nhiều hơn một đối số / tài liệu. $mergeObjects
sau đó kết hợp các tài liệu đó thành một.
Giả sử chúng ta có một tập hợp được gọi là users
với tài liệu sau:
{ "_id" : 1, "name" : { "f_name" : "Homer", "l_name" : "Simpson" }, "contact" : { "email" : "[email protected]", "ph" : null } }
Chúng ta có thể sử dụng $mergeObjects
để hợp nhất name
và contact
lĩnh vực:
db.users.aggregate(
[
{
$project:
{
user: { $mergeObjects: [ "$name", "$contact" ] }
}
}
]
).pretty()
Kết quả:
{ "_id" : 1, "user" : { "f_name" : "Homer", "l_name" : "Simpson", "email" : "[email protected]", "ph" : null } }
Trong trường hợp này, chúng tôi đã hợp nhất cả hai trường thành một trường duy nhất có tên là user
. Nếu chúng tôi có nhiều trường / tài liệu hơn, chúng tôi cũng có thể hợp nhất chúng nếu chúng tôi muốn.
Tên trường trùng lặp
Nếu các tài liệu được hợp nhất chứa các tên trường trùng lặp, $mergeObjects
ghi đè trường khi nó hợp nhất các tài liệu. Do đó, trường trong tài liệu kết quả chứa giá trị từ tài liệu cuối cùng được hợp nhất cho trường đó.
Giả sử chúng ta có tài liệu sau:
{ "_id" : 2, "name" : { "f_name" : "Peter", "l_name" : "Griffin" }, "contact" : { "email" : "[email protected]", "f_name" : "Bart" } }
Chúng ta có thể thấy rằng cả hai tài liệu đều chứa trường có tên f_name
.
Đây là những gì sẽ xảy ra khi chúng tôi hợp nhất các tài liệu đó:
db.users.aggregate(
[
{ $match: { _id: 2 } },
{
$project:
{
user: { $mergeObjects: [ "$name", "$contact" ] }
}
}
]
).pretty()
Kết quả:
{ "_id" : 2, "user" : { "f_name" : "Bart", "l_name" : "Griffin", "email" : "[email protected]" } }
f_name
trường trong tài liệu kết quả chứa Bart
, là giá trị từ tài liệu cuối cùng được hợp nhất.
Giá trị rỗng
Nếu hợp nhất tài liệu với null
, tài liệu kết quả sẽ được trả lại mà không có bất kỳ thay đổi nào.
Nhưng nếu tất cả các tài liệu được hợp nhất là null
, sau đó một tài liệu trống sẽ được trả lại.
Giả sử chúng ta có các tài liệu sau:
{ "_id" : 3, "name" : { "f_name" : "Hubert", "l_name" : "Farnsworth" }, "contact" : null } { "_id" : 4, "name" : null, "contact" : null }
Đây là những gì sẽ xảy ra khi chúng tôi hợp nhất name
và contact
các trường trong hai tài liệu đó:
db.users.aggregate(
[
{ $match: { _id: { $in: [ 3, 4 ] } } },
{
$project:
{
user: { $mergeObjects: [ "$name", "$contact" ] }
}
}
]
)
Kết quả:
{ "_id" : 3, "user" : { "f_name" : "Hubert", "l_name" : "Farnsworth" } } { "_id" : 4, "user" : { } }
Ví dụ về Cú pháp 2 (Đối số Đơn)
Đây là hai ví dụ sử dụng cú pháp đối số duy nhất.
$group
Bộ tích lũy giai đoạn
Trong ví dụ đầu tiên, $mergeObjects
được sử dụng như một $group
tích lũy giai đoạn.
Giả sử chúng ta có một bộ sưu tập được gọi là products
với các tài liệu sau:
{ "_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 } }
Chúng tôi có thể nhóm các tài liệu này theo product
của chúng và sau đó sử dụng $mergeObjects
để hợp nhất inventory
trường cho mỗi nhóm:
db.products.aggregate( [
{ $group: {
_id: "$product",
mergedProducts: { $mergeObjects: "$inventory" }
}
}
]).pretty()
Kết quả:
{ "_id" : "Shorts", "mergedProducts" : { "blue" : 2, "red" : 8, "green" : 5, "black" : 3 } } { "_id" : "Shirt", "mergedProducts" : { "blue" : 10, "red" : 2, "green" : 3, "black" : 1 } }
Mảng
Ví dụ này áp dụng $mergeObjects
vào một tài liệu duy nhất có chứa một trường với một mảng tài liệu.
Giả sử chúng ta có một bộ sưu tập được gọi là test
với các tài liệu sau:
{ "_id" : 1, "data" : [ { "a" : 1, "b" : 2 }, { "c" : 3, "d" : 4 } ] }
Chúng tôi có thể áp dụng $mergeObjects
đến dữ liệu data
lĩnh vực:
db.test.aggregate(
[
{
$project:
{
result: { $mergeObjects: "$data" }
}
}
]
)
Kết quả:
{ "_id" : 1, "result" : { "a" : 1, "b" : 2, "c" : 3, "d" : 4 } }
Các trường bị thiếu
$mergeObjects
bỏ qua bất kỳ trường nào bị thiếu. Có nghĩa là, nếu bạn cung cấp một trường không tồn tại, nó sẽ bỏ qua nó. Nếu không có trường nào tồn tại, thì nó trả về một tài liệu trống.
Ví dụ:
db.users.aggregate(
[
{
$project:
{
user: { $mergeObjects: [ "$name", "$oops" ] }
}
}
]
).pretty()
Kết quả:
{ "_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" : { } }
Tuy nhiên, đây là những gì sẽ xảy ra khi không có trong số các trường tồn tại:
db.users.aggregate(
[
{
$project:
{
user: { $mergeObjects: [ "$wrong", "$oops" ] }
}
}
]
).pretty()
Kết quả:
{ "_id" : 1, "user" : { } } { "_id" : 2, "user" : { } } { "_id" : 3, "user" : { } } { "_id" : 4, "user" : { } }
Kết quả là một tài liệu trống.
Điều này cũng giống như khi sử dụng cú pháp một đối số.
Ví dụ:
db.products.aggregate( [
{ $group: {
_id: "$product",
mergedProducts: { $mergeObjects: "$oops!" }
}
}
]).pretty()
Kết quả:
{ "_id" : "Shorts", "mergedProducts" : { } } { "_id" : "Shirt", "mergedProducts" : { } }