MongoDB聚合查询如何按用户分组后取URL下各关键词最新排名
问题说明
你现有的聚合查询直接将用户所有排名记录推入data数组,没有做两层分组(先按URL+关键词去重取最新,再按URL聚合关键词),所以会出现重复的关键词记录。
修改后的聚合查询
Rank.aggregate([ { $match: {} }, { $lookup: { from: 'users', localField: 'user', foreignField: '_id', as: 'user' } }, { $project: { user: { $arrayElemAt: ['$user', 0] }, url: 1, keyword: 1, rank: 1, createdAt: 1 } }, // 先按创建时间倒排,保证最新记录排在最前 { $sort: { createdAt: -1 } }, // 第一层分组:按用户ID+URL+关键词分组,取每个关键词最新的一条记录 { $group: { _id: { userId: '$user._id', url: '$url', keyword: '$keyword' }, user: { $first: '$user' }, rank: { $first: '$rank' }, createdAt: { $first: '$createdAt' } } }, // 第二层分组:按用户ID+URL分组,把同URL下的所有关键词收拢到keywords数组 { $group: { _id: { userId: '$_id.userId', url: '$_id.url' }, user: { $first: '$user' }, keywords: { $push: { keyword: '$_id.keyword', rank: '$rank', createdAt: '$createdAt' } } } }, // 第三层分组:按用户ID分组,把同用户下的所有URL记录收拢到data数组 { $group: { _id: '$_id.userId', user: { $first: '$user' }, data: { $push: { url: '$_id.url', keywords: '$keywords' } } } }, // 可选:去掉输出里的_id字段,和预期格式对齐 { $project: { _id: 0 } } ])
逻辑说明
- 排序后第一次按
用户ID+URL+关键词分组,利用$first直接拿到每个关键词最新的排名记录,实现关键词去重取最新的需求 - 第二次按
用户ID+URL分组,把同一个URL下的所有去重后的关键词收拢成keywords数组 - 最后按用户ID分组,把同一个用户下的所有URL数据收拢成
data数组,和你给出的预期输出结构完全匹配
内容的提问来源于stack exchange,提问作者Alex Fadeev
相关产品推荐
相关产品推荐

