MongoDB聚合查询实现:门店图片展示与双类型统计
Hey there! Let's sort out your MongoDB aggregation query. The problem with your original pipeline is that each stage runs in sequence—you first filter only for imageType: 1 documents, then later try to count both imageType:1 and 3, which won't work because the later stages only have access to the docs that passed the first $match. Plus, the $count stage would overwrite all the previous projection data, so you can't get both the image list and total count in one result that way.
Here's the corrected aggregation that will give you exactly the expected output:
db.images.aggregate([ // Step 1: Filter all relevant documents for the target store (both image types 1 and 3) { $match: { storeId: storeId, imageType: { $in: [1, 3] } } }, // Step 2: Use $facet to run two parallel pipelines { $facet: { // Pipeline A: Fetch store owner's images (imageType:1) with desired fields images: [ { $match: { imageType: 1 } }, { $project: { _id: 0, imageId: 1, reviewId: 1, storeId: 1, username: 1, image: 1, imageType: 1, likes: 1, dislikes: 1, status: 1 } } ], // Pipeline B: Count total number of qualifying images (1 + 3) total_count: [ { $count: "total_image_count" } ] } }, // Step 3: Merge the facet results into a clean, single document { $project: { images: 1, total_image_count: { $arrayElemAt: ["$total_count.total_image_count", 0] } } } ])
How this works:
- Initial
$match: We first narrow down the dataset to only documents for your target store that are eitherimageType:1(owner-uploaded) orimageType:3(user-uploaded). This is efficient because it reduces the number of docs processed in later stages. $facetStage: This lets us run two independent pipelines at the same time:- The
imagespipeline filters for only owner-uploaded images (imageType:1) and projects exactly the fields you need (matching your expected result structure). - The
total_countpipeline counts all the documents that passed the initial filter (so both types 1 and 3 combined).
- The
- Final
$project: We extract the total count from thetotal_countarray (since$countreturns an array with one document) and make it a top-level field, alongside theimagesarray.
Test with your sample data:
For the sample documents you provided, this query will return:
{ "images": [ { "imageId": "siyaram_image_1", "reviewId": "#review_id", "storeId": "#store_id", "username": "abc@xyz.com", "image": "reviews/siyaram_image_1.jpg", "imageType": 1, "likes": 0, "dislikes": 0, "status": 4 }, { "imageId": "siyaram_image_2", "reviewId": "#review_id", "storeId": "#store_id", "username": "abc@xyz.com", "image": "reviews/siyaram_image_2.jpg", "imageType": 1, "likes": 0, "dislikes": 0, "status": 4 } ], "total_image_count": 5 }
Which matches exactly the expected result you outlined!
内容的提问来源于stack exchange,提问作者Vikas Valechha

