Você pode usar o
$cond
operador em um $project
stage para substituir o attr
vazio array com um que contém um espaço reservado como null
que pode ser usado como um marcador para indicar que este documento não contém nenhum attr
elementos. Então você inseriria um
$project
adicional estágio como este logo antes do $unwind
: {
$project: {
attrs: {$cond: {
if: {$eq: ['$attrs', [] ]},
then: [null],
else: '$attrs'
}}
}
},
A única ressalva é que você terminará com um
null
valor no attrs
final array para os grupos que contêm pelo menos um doc sem nenhum attrs
elementos, então você precisa ignorá-los do lado do cliente. Exemplo
O exemplo usa um
$match
alterado stage porque o do seu exemplo não é válido. Inserir documentos
[
{_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}]}
]
Saída
{
"result" : [
{
"_id" : 1,
"attrs" : [
null
]
},
{
"_id" : 2,
"attrs" : [
{
"name" : "bob",
"type" : 44
},
{
"name" : "john",
"type" : 22
},
null
]
}
],
"ok" : 1
}
Comando Agregado
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
}
}
])