MongoDB聚合关联集合查询用户最新事件创建时间方法
MongoDB 聚合实现用户关联事件最大时间查询方案
核心逻辑说明
你已完成的$match+$lookup阶段已经实现了按账号筛选用户、关联对应用户所有事件记录的能力,关联后每个用户文档会携带userEvents数组,存放该用户关联到的所有productevents记录。后续仅需简单的字段计算、字段裁剪阶段即可得到和两类SQL完全一致的返回结果:
- 如果要等价SQL1关联子查询效果:无事件记录的用户也会返回,对应最大事件时间为
null - 如果要等价SQL2内连接分组效果:无事件记录的用户不返回,仅保留存在关联事件的用户
完整聚合代码
[ { $match: { accountId: '629a251af534a3600aa1a150' } }, { $lookup: { from: 'productevents', localField: 'id', foreignField: 'userId', as: 'userEvents' } }, // 开启下方阶段即可等价SQL2内连接效果,注释则等价SQL1关联子查询效果 // { // $match: { // "userEvents.0": { $exists: true } // } // }, { $addFields: { lastEventCreatedAt: { $max: "$userEvents.createdAt" } } }, { $project: { id: 1, name: 1, lastEventCreatedAt: 1, _id: 0 } } ]
关键阶段解释
- 内连接过滤阶段:通过判断
userEvents数组是否存在第0个元素,过滤掉没有关联事件的用户,和SQL内连接逻辑完全一致,性能比判断$ne: []更高。 - 最大值计算阶段:直接使用
$max运算符读取userEvents.createdAt路径,MongoDB会自动遍历数组内所有元素提取createdAt字段并返回最大值,无需手动拆分数组,性能远高于$unwind+$group的常规分组写法。 - 字段裁剪阶段:通过
$project只保留需要返回的id、name、计算得到的最大事件时间字段,移除中间关联产生的userEvents数组和其他无关字段,和SQL查询返回字段对齐。
样例返回结果
基于你提供的测试数据,执行后返回结果如下:
{ "id": "1", "name": "Some User", "lastEventCreatedAt": { "$date": "2022-06-03T07:14:49.432Z" } }
内容的提问来源于stack exchange,提问作者Luis Novo
相关产品推荐
相关产品推荐

