Bạn có thể sử dụng $cond
toán tử trong $project
giai đoạn để thay thế attr
trống mảng với một mảng có chứa trình giữ chỗ như null
có thể được sử dụng làm điểm đánh dấu để cho biết rằng tài liệu này không chứa bất kỳ attr
nào các phần tử.
Vì vậy, bạn sẽ chèn thêm một $project
giai đoạn như thế này ngay trước $unwind
:
{
$project: {
attrs: {$cond: {
if: {$eq: ['$attrs', [] ]},
then: [null],
else: '$attrs'
}}
}
},
Cảnh báo duy nhất là bạn sẽ kết thúc bằng null
giá trị trong attrs
cuối cùng mảng cho những nhóm chứa ít nhất một tài liệu mà không có bất kỳ attrs
, vì vậy bạn cần bỏ qua những yếu tố phía máy khách đó.
Ví dụ
Ví dụ sử dụng $match
đã thay đổi vì cái trong ví dụ của bạn không hợp lệ.
Tài liệu đầu vào
[
{_id: {type: 1, id: 2}, attrs: []},
{_id: {type: 2, id: 1}, attrs: []},
{_id: {type: 2, id: 2}, attrs: [{name: 'john', type: 22}, {name: 'bob', type: 44}]}
]
Đầu ra
{
"result" : [
{
"_id" : 1,
"attrs" : [
null
]
},
{
"_id" : 2,
"attrs" : [
{
"name" : "bob",
"type" : 44
},
{
"name" : "john",
"type" : 22
},
null
]
}
],
"ok" : 1
}
Lệnh tổng hợp
db.test.aggregate([
{
$match: {
'_id.servicePath': {
$in: [
null
]
}
}
},
{
$project: {
_id: 1,
"attrs.name": 1,
"attrs.type": 1
}
},
{
$project: {
attrs: {$cond: {
if: {$eq: ['$attrs', [] ]},
then: [null],
else: '$attrs'
}}
}
},
{
$unwind: "$attrs"
},
{
$group: {
_id: "$_id.type",
attrs: {
$addToSet: "$attrs"
}
}
},
{
$sort: {
_id: 1
}
}
])