MongoDB如何查询两日期字段与传入起止日期区间匹配的数据
MongoDB查询指定日期区间内有效员工的实现方法
区间匹配核心逻辑
要找出有效期和传入查询区间[2022-05-01, 2022-05-31]存在重叠的文档,需满足时间区间交集规则,两个条件必须同时成立:
- 文档的有效期开始时间
effct_bgn_dt小于等于 查询区间的结束时间 - 文档的有效期结束时间
effct_end_dt大于等于 查询区间的开始时间
注意:存储的日期带
+05:30时区偏移,构造查询条件时需要将传入的日期字符串转为相同时区的ISODate类型,避免时区偏差导致查询结果出错。
不要使用「文档生效时间 >= 查询开始 且 文档失效时间 <= 查询结束」的错误写法,该逻辑只会返回有效期完全落在查询区间内的文档,会漏掉类似样例中第一条4月生效、5月仍在有效期内的记录。
基础查询(返回匹配的完整文档)
执行find查询即可过滤掉不符合要求的文档,对应样例数据会自动排除第三条8-10月生效的记录,仅返回前两条符合条件的文档:
// 替换为实际集合名,日期值根据接口传入参数转换即可 const queryStart = ISODate("2022-05-01T00:00:00.000+05:30") const queryEnd = ISODate("2022-05-31T23:59:59.999+05:30") db.your_collection_name.find({ effct_bgn_dt: { $lte: queryEnd }, effct_end_dt: { $gte: queryStart } })
聚合查询(直接返回合并后的员工ID集合)
如果不需要返回完整文档,直接获取所有匹配的员工ID(自动去重),可以使用聚合管道实现,输出结果和预期的[114,118,117,115]一致:
db.your_collection_name.aggregate([ // 第一步:过滤有效期匹配的文档 { $match: { effct_bgn_dt: { $lte: queryEnd }, effct_end_dt: { $gte: queryStart } } }, // 第二步:拆分员工数组,将每个员工ID转为独立记录 { $unwind: "$emp_list" }, // 第三步:分组去重,合并所有员工ID { $group: { _id: null, emp_id_list: { $addToSet: "$emp_list" } } }, // 第四步:移除多余字段,仅返回员工ID集合 { $project: { _id: 0, emp_id_list: 1 } } ])
如果需要返回数字类型的员工ID,只需要在$project阶段增加$toInt转换逻辑即可。
内容的提问来源于stack exchange,提问作者Lokesh R
相关产品推荐
相关产品推荐

