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