I have a mongo document like this where usage
is a map, so field names are not constant, it contains an array of unique seats that I want to count for each object:
{
"usage" : {
"maxNumberOfAddresses" : {
"seats" : [
"193.34.136.242",
"138.61.33.44",
"96.160.197.255",
"151.34.143.231",
"255.90.212.146",
"182.57.86.6",
"102.171.187.32",
"150.157.38.224",
"207.156.239.153",
"59.194.105.191"
]
},
"totalUsers" : {
"seats" : [
"123",
"456",
"789",
]
}
}
},
I want to construct an aggregation that would return an object with sizes for each seats
array in a map:
{
"usage" : {
"maxNumberOfAddresses" : {
"total" : 10
},
"totalUsers" : {
"total" : 3
}
}
},
I've tried a query like this, but it seems the wildcard doesn't work inside usage
db.seats.projection({
"usage.*.seats": {
$cond: {
if: { $isArray: 'usage.*.seats' },
then: { total: 'usage.*.seats' },
else: 'NA',
},
},
})
Any idea how to properly construct a query like this?
CodePudding user response:
One option is using $objectToArray
and $arrayToObject
:
db.collection.aggregate([
{$project: {usage: {$objectToArray: "$usage"}}},
{$project: {usage: {
$map: {
input: "$usage",
in: {k: "$$this.k", v: {total: {$size: "$$this.v.seats"}}}}
}
}
},
{$project: {usage: {$arrayToObject: "$usage"}}}
])
See how it works on the playground example