Du kan bruge $cond
operatør i et $project trin for at erstatte den tomme attr array med en, der indeholder en pladsholder som null der kan bruges som en markør for at angive, at dette dokument ikke indeholder nogen attr elementer.
Så du ville indsætte et ekstra $project trin som dette lige før $unwind :
{
$project: {
attrs: {$cond: {
if: {$eq: ['$attrs', [] ]},
then: [null],
else: '$attrs'
}}
}
},
Den eneste advarsel er, at du ender med en null værdi i den endelige attrs array for de grupper, der indeholder mindst ét dokument uden nogen attrs elementer, så du skal ignorere disse klientside.
Eksempel
Eksemplet bruger en ændret $match fase, fordi den i dit eksempel ikke er gyldig.
Inputdokumenter
[
{_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}]}
]
Output
{
"result" : [
{
"_id" : 1,
"attrs" : [
null
]
},
{
"_id" : 2,
"attrs" : [
{
"name" : "bob",
"type" : 44
},
{
"name" : "john",
"type" : 22
},
null
]
}
],
"ok" : 1
}
Samlet 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
}
}
])