MongoDB数组过滤聚合:按标签分组统计无结果问题排查
Hey there! Let's break down why your aggregation is returning 0 documents, and how to get the expected results.
The Root Problem: Pipeline Stage Order
MongoDB executes aggregation stages in the exact order you define them, and that's where your code went wrong. You first grouped all documents by their full tags array, then tried to match on a tags field—but after grouping, the output documents don't have a top-level tags field anymore!
Your original pipeline creates documents that look like this after the $group stage:
{ _id: { tags: ['video', 'Alex'] }, total: 1 }
There's no tags field to match against, so the subsequent $match stage finds zero matches.
The Corrected Pipeline
You need to filter first, then group. Here's the fixed code:
client.db('mydb').collection('Files').aggregate([ // Step 1: Filter documents that include the 'video' tag { $match: { tags: 'video' } }, // Step 2: Group by the full tags array and count occurrences { $group: { _id: '$tags', total: { $sum: 1 } } } ]).toArray()
How This Works
- $match First: This stage filters out all documents where the
tagsarray doesn't include 'video'. From your sample data, this leaves 3 documents:{tags: ['video', 'Alex'], ... }{tags: ['video', 'John'], ... }{tags: ['video', 'John'], ... }
- $group Second: Now we group these filtered documents by their full
tagsarray. This gives you exactly the expected result:[ { _id: ['video', 'Alex'], total: 1 }, { _id: ['video', 'John'], total: 2 } ]
Quick Note on Matching Array Elements
MongoDB's default behavior for { tags: 'video' } is to match any document where the tags array contains 'video'—which is exactly what you need here, so no need for extra operators like $elemMatch or $in in this case.
内容的提问来源于stack exchange,提问作者Alexey Sviridov

