It can't allow $size as accumulator operator,
The $group's field Computed using the accumulator operators. The operator must be one of the following accumulator operators are: $accumulator, $addToSet, $avg, $first, $last, $max, $mergeObjects, $min, $push, $stdDevPop, $stdDevSamp, $sum, for more details refer $group,
- use
$sum before $size operator,
let topics = await ReadSchema.aggregate([
{
$group: {
"_id": "$id",
count: {
$sum: {
$size: {
"$ifNull": [ "$summary.topics", [] ]
}
}
}
}
}
]);
Remove duplicate topics in the total:
$addToSet to topics, make unique array of topics array
$reduce to iterate loop of topics array and get union of all topics tags
using $setUnion and, $size to get total count of unique topics
let topics = await ReadSchema.aggregate([
{
$group: {
_id: "$id",
topics: {
$addToSet: { $ifNull: [ "$summary.topics", [] ] }
}
}
},
{
$project: {
id: 1,
count: {
$size: {
$reduce: {
input: "$topics",
initialValue: [],
in: { $setUnion: ["$$this", "$$value"] }
}
}
}
}
}
])
Suggestions:
- match topics is array condition in first stage in your query,
$type: 4 indicates topics field has array data type or not, this will filter your documents before $group stage and you do not longer need to check $ifNull condition in $group stage, you can remove that condition.
- for query optimization you can put index on
summary.topics field.
{
$match: {
$and: [
{ "summary.topics": { $type: 4 } },
{ "summary.topics": { $ne: [] } }
]
}
}