Du kan använda $cond
operatör i ett $project
steg för att ersätta den tomma attr
array med en som innehåller en platshållare som null
som kan användas som en markör för att indikera att detta dokument inte innehåller någon attr
element.
Så du skulle infoga ytterligare ett $project
skede så här precis innan $unwind
:
{
$project: {
attrs: {$cond: {
if: {$eq: ['$attrs', [] ]},
then: [null],
else: '$attrs'
}}
}
},
Den enda varningen är att du kommer att få en null
värde i den sista attrs
array för de grupper som innehåller minst ett dokument utan någon attrs
element, så du måste ignorera de klientsidan.
Exempel
Exemplet använder en ändrad $match
steg eftersom den i ditt exempel inte är giltig.
Inmatningsdokument
[
{_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}]}
]
Utdata
{
"result" : [
{
"_id" : 1,
"attrs" : [
null
]
},
{
"_id" : 2,
"attrs" : [
{
"name" : "bob",
"type" : 44
},
{
"name" : "john",
"type" : 22
},
null
]
}
],
"ok" : 1
}
Aggregerat kommando
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
}
}
])