Sie können den $cond
Operator in einem $project Stufe, um das leere attr zu ersetzen Array mit einem, das einen Platzhalter wie null enthält die als Markierung verwendet werden kann, um anzuzeigen, dass dieses Dokument kein attr enthält Elemente.
Sie würden also ein zusätzliches $project einfügen Bühne wie diese direkt vor dem $unwind :
{
$project: {
attrs: {$cond: {
if: {$eq: ['$attrs', [] ]},
then: [null],
else: '$attrs'
}}
}
},
Die einzige Einschränkung ist, dass Sie am Ende einen null erhalten Wert in den abschließenden attrs Array für die Gruppen, die mindestens ein Dokument ohne attrs enthalten Elemente, daher müssen Sie diese clientseitigen Elemente ignorieren.
Beispiel
Das Beispiel verwendet ein verändertes $match Stufe, weil die in Ihrem Beispiel nicht gültig ist.
Dokumente eingeben
[
{_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}]}
]
Ausgabe
{
"result" : [
{
"_id" : 1,
"attrs" : [
null
]
},
{
"_id" : 2,
"attrs" : [
{
"name" : "bob",
"type" : 44
},
{
"name" : "john",
"type" : 22
},
null
]
}
],
"ok" : 1
}
Aggregatbefehl
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
}
}
])