Trong MongoDB, $setUnion
toán tử đường ống tổng hợp chấp nhận hai hoặc nhiều mảng và trả về một mảng chứa các phần tử xuất hiện trong bất kỳ mảng đầu vào nào.
$setUnion
chấp nhận hai hoặc nhiều đối số, tất cả đều có thể là bất kỳ biểu thức hợp lệ nào miễn là mỗi đối số phân giải thành một mảng. $setUnion
coi các mảng là tập hợp.
Ví dụ
Giả sử chúng ta có một tập hợp được gọi là data
với các tài liệu sau:
{"_id":1, "a":[1, 2, 3], "b":[1, 2, 3]} {"_id":2, "a":[1, 2, 3], "b":[1, 2]} {"_id":3, "a":[1, 2], "b":[1, 2, 3]} {"_id":4, " a ":[1, 2, 3]," b ":[3, 4, 5]} {" _id ":5," a ":[1, 2, 3]," b ":[4, 5 , 6]}
Chúng tôi có thể áp dụng $setUnion
toán tử so với a
và b
các trường trong các tài liệu đó.
Ví dụ:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 1, 2, 3, 4, 5 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
result: { $setUnion: [ "$a", "$b" ] }
}
}
]
)
Kết quả:
{"a":[1, 2, 3], "b":[1, 2, 3], "result":[1, 2, 3]} {"a":[1, 2, 3], "b":[1, 2], "result":[1, 2, 3]} {"a":[1, 2], "b":[1, 2, 3], "result ":[1, 2, 3]} {" a ":[1, 2, 3]," b ":[3, 4, 5]," result ":[1, 2, 3, 4, 5] } {"a":[1, 2, 3], "b":[4, 5, 6], "result":[1, 2, 3, 4, 5, 6]}
Mảng lồng nhau
$setUnion
toán tử không đi xuống bất kỳ mảng lồng nhau nào. Nó chỉ đánh giá các mảng cấp cao nhất.
Giả sử bộ sưu tập của chúng tôi cũng chứa các tài liệu sau:
{"_id":6, "a":[1, 2, 3], "b":[[1, 2, 3]]} {"_id":7, "a":[1, 2, 3], "b":[[1, 2], 3]} {"_id":8, "a":[[1, 2, 3]], "b":[[1, 2, 3]]} {"_id":9, "a":[[1, 2, 3]], "b":[[1, 2], 3]}
Và chúng tôi áp dụng $setUnion
cho hai tài liệu đó:
db.data.aggregate(
[
{ $match: { _id: { $in: [ 6, 7, 8, 9 ] } } },
{
$project:
{
_id: 0,
a: 1,
b: 1,
result: { $setUnion: [ "$a", "$b" ] }
}
}
]
)
Kết quả:
{"a":[1, 2, 3], "b":[[1, 2, 3]], "result":[1, 2, 3, [1, 2, 3]]} {"a":[1, 2, 3], "b":[[1, 2], 3], "result":[1, 2, 3, [1, 2]]} {"a":[[1, 2, 3]], "b":[[1, 2, 3]], "result":[[1, 2, 3]]} {"a":[[1, 2, 3 ]], "b":[[1, 2], 3], "kết quả":[3, [1, 2], [1, 2, 3]]}
Các trường bị thiếu
Áp dụng $setUnion
đến một trường không tồn tại dẫn đến null
.
Xem xét các tài liệu sau:
{"_id":10, "a":[1, 2, 3]} {"_id":11, "b":[1, 2, 3]} {"_id":12}Tài liệu đầu tiên không có
b
trường, tài liệu thứ hai không cóa
và tài liệu thứ ba cũng không có.Đây là những gì sẽ xảy ra khi chúng tôi áp dụng
$setUnion
tớia
vàb
lĩnh vực:db.data.aggregate( [ { $match: { _id: { $in: [ 10, 11, 12 ] } } }, { $project: { _id: 0, a: 1, b: 1, result: { $setUnion: [ "$a", "$b" ] } } } ] )
Kết quả:
{"a":[1, 2, 3], "result":null} {"b":[1, 2, 3], "result":null} {"result":null}Loại dữ liệu sai
Tất cả các toán hạng của
$setUnion
phải là mảng. Nếu không, một lỗi sẽ xảy ra.Giả sử bộ sưu tập của chúng tôi chứa các tài liệu sau:
{"_id":13, "a":[1, 2, 3], "b":3} {"_id":14, "a":3, "b":[1, 2, 3]} {"_id":15, "a":2, "b":3}Và chúng tôi áp dụng
$setUnion
đối với các tài liệu đó:db.data.aggregate( [ { $match: { _id: { $in: [ 13, 14, 15 ] } } }, { $project: { _id: 0, a: 1, b: 1, result: { $setUnion: [ "$a", "$b" ] } } } ] )
Kết quả:
Lỗi:lệnh không thành công:{"ok":0, "errmsg":"Tất cả các toán hạng của $ setUnion phải là mảng. Một đối số thuộc loại:double", "code":17043, "codeName":"Location17043 "}:tổng hợp không thành công:[email protected]/mongo/shell/utils.js:25:[email protected]/mongo/shell/assert.js:18:[email protected]/mongo/shell/assert. js:639:[email protected]/mongo/shell/assert.js:729:[email protected]/mongo/shell/db.js:266:[email protected]/mongo/shell/collection.js:1058:12 @ (shell):1:1Giá trị trùng lặp
$setUnion
toán tử lọc ra các bản sao trong kết quả của nó để xuất ra một mảng chỉ chứa các mục nhập duy nhất. Ngoài ra, thứ tự của các phần tử trong mảng đầu ra là không xác định.Giả sử chúng ta có các tài liệu sau:
{"_id":16, "a":[1, 1, 2, 2, 3, 3], "b":[1, 2, 3]} {"_id":17, "a" :[1, 1, 2, 2, 3, 3], "b":[1, 1, 2]} {"_id":18, "a":[1, 1, 2, 2, 3, 3 ], "b":[]} {"_id":19, "a":[3, 2, 1, 2, 3, 1], "b":[2, 3, 1]} {"_id" :20, "a":[1, 3, 2, 2, 3, 1], "b":[2, 1]} {"_id":21, "a":[2, 3, 1, 2 , 3, 1], "b":[]}Sau đó, chúng tôi áp dụng
$setUnion
toán tử cho họ:db.data.aggregate( [ { $match: { _id: { $in: [ 16, 17, 18, 19, 20, 21 ] } } }, { $project: { _id: 0, a: 1, b: 1, result: { $setUnion: [ "$a", "$b" ] } } } ] )
Kết quả:
{"a":[1, 1, 2, 2, 3, 3], "b":[1, 2, 3], "result":[1, 2, 3]} {"a" :[1, 1, 2, 2, 3, 3], "b":[1, 1, 2], "result":[1, 2, 3]} {"a":[1, 1, 2 , 2, 3, 3], "b":[], "result":[1, 2, 3]} {"a":[3, 2, 1, 2, 3, 1], "b":[2, 3, 1], "result":[1, 2, 3]} {"a":[1, 3, 2, 2, 3, 1], "b":[2, 1], " result ":[1, 2, 3]} {" a ":[2, 3, 1, 2, 3, 1]," b ":[]," result ":[1, 2, 3]}Nhiều hơn hai đối số
Như đã đề cập,
$setUnion
chấp nhận hai hoặc nhiều đối số. Tất cả các ví dụ trước đều sử dụng hai đối số. Đây là một trong những sử dụng ba đối số.Giả sử chúng ta có các tài liệu sau:
{"_id":22, "a":[1, 2], "b":[1, 2], "c":[1, 2]} {"_id":23, "a" :[1, 2], "b":[1, 2], "c":[1, 2, 3]} {"_id":24, "a":[1, 2], "b":[1, 2], "c":[4, 5]}Các tài liệu này có thêm một trường - a
c
trường.Bây giờ hãy áp dụng
$setUnion
cho ba trường đó:db.data.aggregate( [ { $match: { _id: { $in: [ 22, 23, 24 ] } } }, { $project: { _id: 0, a: 1, b: 1, c: 1, result: { $setUnion: [ "$a", "$b", "$c" ] } } } ] )
Kết quả:
{"a":[1, 2], "b":[1, 2], "c":[1, 2], "result":[1, 2]} {"a":[ 1, 2], "b":[1, 2], "c":[1, 2, 3], "result":[1, 2, 3]} {"a":[1, 2], "b":[1, 2], "c":[4, 5], "kết quả":[1, 2, 4, 5]}