Vous pouvez utiliser le $cond
opérateur dans un $project
étape pour remplacer le attr
vide tableau avec un qui contient un espace réservé comme null
qui peut être utilisé comme marqueur pour indiquer que ce document ne contient aucun attr
éléments.
Vous insérez donc un $project
supplémentaire étape comme celle-ci juste avant le $unwind
:
{
$project: {
attrs: {$cond: {
if: {$eq: ['$attrs', [] ]},
then: [null],
else: '$attrs'
}}
}
},
La seule mise en garde est que vous vous retrouverez avec un null
valeur dans le dernier attrs
tableau pour les groupes contenant au moins un document sans aucun attrs
éléments, vous devez donc ignorer ceux côté client.
Exemple
L'exemple utilise un $match
modifié étape car celle de votre exemple n'est pas valide.
Saisir des documents
[
{_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}]}
]
Sortie
{
"result" : [
{
"_id" : 1,
"attrs" : [
null
]
},
{
"_id" : 2,
"attrs" : [
{
"name" : "bob",
"type" : 44
},
{
"name" : "john",
"type" : 22
},
null
]
}
],
"ok" : 1
}
Commande d'agrégation
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
}
}
])