MST

星途 面试题库

面试题:MongoDB聚合管道优化与嵌套操作

现有一个庞大的`product_reviews`集合,文档包含`product_id`(产品编号)、`reviewer_id`(评论者编号)、`review_date`(评论日期)、`rating`(评分,1 - 5分)、`comments`(评论内容)。业务需求是先按照`product_id`分组,筛选出评论数量超过100且平均评分大于4分的产品。对于这些满足条件的产品,再按照`reviewer_id`进一步分组,找出每个评论者对该产品的评论次数、最早评论日期和最晚评论日期。在数据量较大的情况下,如何优化聚合管道操作以提高执行效率,并给出完整的聚合管道代码。
48.2万 热度难度
数据库MongoDB

知识考点

AI 面试

面试题答案

一键面试
  1. 优化思路
    • 尽量在管道早期阶段过滤掉不必要的数据,减少后续处理的数据量。
    • 使用索引来加速查询,对于product_idreviewer_id等频繁用于分组和过滤的字段创建复合索引。
  2. 聚合管道代码
db.product_reviews.aggregate([
    // 按product_id分组,计算每个产品的评论数量和平均评分
    {
        $group: {
            _id: "$product_id",
            reviewCount: { $sum: 1 },
            averageRating: { $avg: "$rating" }
        }
    },
    // 筛选评论数量超过100且平均评分大于4分的产品
    {
        $match: {
            reviewCount: { $gt: 100 },
            averageRating: { $gt: 4 }
        }
    },
    // 展开符合条件的产品的评论数据,以便进一步按reviewer_id分组
    {
        $lookup: {
            from: "product_reviews",
            localField: "_id",
            foreignField: "product_id",
            as: "productReviews"
        }
    },
    {
        $unwind: "$productReviews"
    },
    // 按product_id和reviewer_id分组,计算评论次数、最早和最晚评论日期
    {
        $group: {
            _id: {
                product_id: "$_id",
                reviewer_id: "$productReviews.reviewer_id"
            },
            reviewCountByReviewer: { $sum: 1 },
            earliestReviewDate: { $min: "$productReviews.review_date" },
            latestReviewDate: { $max: "$productReviews.review_date" }
        }
    },
    // 重塑结果,使结构更清晰
    {
        $project: {
            product_id: "$_id.product_id",
            reviewer_id: "$_id.reviewer_id",
            reviewCountByReviewer: 1,
            earliestReviewDate: 1,
            latestReviewDate: 1,
            _id: 0
        }
    }
]);
  1. 索引创建
db.product_reviews.createIndex({ product_id: 1, reviewer_id: 1 });