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
}
}
])