U kunt de $cond
operator in een $project
stage om de lege attr
. te vervangen array met een die een tijdelijke aanduiding bevat zoals null
die kan worden gebruikt als een markering om aan te geven dat dit document geen attr
. bevat elementen.
Dus je zou een extra $project
. invoegen podium zoals dit vlak voor de $unwind
:
{
$project: {
attrs: {$cond: {
if: {$eq: ['$attrs', [] ]},
then: [null],
else: '$attrs'
}}
}
},
Het enige voorbehoud is dat je eindigt met een null
waarde in de laatste attrs
array voor die groepen die ten minste één document bevatten zonder attrs
elementen, dus je moet die client-side negeren.
Voorbeeld
Het voorbeeld gebruikt een gewijzigde $match
omdat die in uw voorbeeld niet geldig is.
Documenten invoeren
[
{_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}]}
]
Uitvoer
{
"result" : [
{
"_id" : 1,
"attrs" : [
null
]
},
{
"_id" : 2,
"attrs" : [
{
"name" : "bob",
"type" : 44
},
{
"name" : "john",
"type" : 22
},
null
]
}
],
"ok" : 1
}
Geaggregeerde opdracht
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
}
}
])