如何在MongoDB集合中按医院ID获取每日最后一条Entry文档?
在MongoDB中实现按医院ID分组获取每日最后一条记录
好的,我来帮你搞定这个需求!在MongoDB里,我们可以用**聚合管道(Aggregation Pipeline)**来实现和MySQL INNER JOIN等价的效果,完全贴合文档型数据库的特性。下面是具体的实现方案:
核心思路
和MySQL的思路异曲同工:
- 先找出每个「医院ID+日期」分组下的最新记录时间戳(也就是当天的最大时间戳)
- 再通过这个时间戳关联原集合,取出对应的完整文档
具体聚合代码(MongoDB 5.0+推荐)
这个版本用$dateTrunc快速按天截断时间戳,语法更简洁直观:
db.entry.aggregate([ // 步骤1:将时间戳转换为「日期天」格式,方便按天分组 { $addFields: { "day": { $dateTrunc: { date: { $toDate: "$date" }, // 把时间戳转成MongoDB日期类型 unit: "day" // 按天截断,得到当天的起始时间 } } } }, // 步骤2:按医院ID和日期分组,获取每个分组的最新时间戳 { $group: { _id: { hospitalId: "$hospital._id", day: "$day" }, maxDate: { $max: "$date" } // 取分组内最大的时间戳,即当天最后一条记录的时间 } }, // 步骤3:关联原entry集合,匹配对应医院ID和最新时间戳的完整记录 { $lookup: { from: "entry", let: { targetHospitalId: "$_id.hospitalId", targetDate: "$maxDate" }, pipeline: [ { $match: { $expr: { $and: [ { $eq: ["$hospital._id", "$$targetHospitalId"] }, { $eq: ["$date", "$$targetDate"] } ] } } } ], as: "dailyLastRecord" } }, // 步骤4:展开获取的记录数组(每个分组只会有一条结果) { $unwind: "$dailyLastRecord" }, // 可选步骤:调整输出结构,只保留你需要的字段 { $project: { _id: "$dailyLastRecord._id", date: "$dailyLastRecord.date", hospital: "$dailyLastRecord.hospital", // 这里可以添加其他需要的字段,比如医院名称、其他详情等 recordDay: "$_id.day" } } ])
兼容低版本MongoDB(5.0以下)
如果你的MongoDB版本低于5.0,没有$dateTrunc,可以用$dateToString生成日期字符串作为分组依据:
把步骤1的$addFields替换成:
{ $addFields: { "day": { $dateToString: { format: "%Y-%m-%d", // 输出类似"2020-06-29"的日期字符串 date: { $toDate: "$date" } } } } }
关键细节说明
$toDate是把你的时间戳字段date转换成MongoDB的日期类型,这样才能进行日期截断/格式化操作$group阶段的_id是复合键,同时包含医院ID和日期,确保我们是按「每个医院每天」来分组$lookup这里用了子管道(pipeline参数)来精准匹配,比简单的字段匹配更灵活,也能避免不必要的数据关联- 如果同一医院同一天有多个记录的时间戳完全相同(极端情况),
$max会保留最大的那个;你也可以在$group前先按date降序排序,再用$last取记录,但$max的方式性能更优
内容的提问来源于stack exchange,提问作者Atharv Kurdukar
相关产品推荐
相关产品推荐

