MongoDB中创建不与已有时段重叠的时间槽的技术问题
解决MongoDB时间槽重叠检测问题
示例MongoDB文档
注意:原文档中第三条数据的start_time存在格式错误(多了一个无效的0),已修正为正确格式:
db={ "teacher": [ { "id": 1276, "start_time": "2023-03-22T07:00:25.787Z", "end_time": "2023-03-22T10:00:35.604Z" }, { "id": 1564, "start_time": "2023-03-22T07:00:25.787Z", "end_time": "2023-03-22T10:00:35.604Z" }, { "id": 1276, "start_time": "2023-03-22T11:00:25.787Z", "end_time": "2023-03-22T15:00:35.604Z" } ] }
当前查询的问题
原查询仅通过$or判断新时间槽的开始/结束时间落在已有时间槽范围内,未覆盖新时间槽完全包含已有时间槽或已有时间槽完全包含新时间槽的重叠场景,导致检测结果不准确。
原查询代码:
db.teacher.find({ id: 1276, $or: [ { start_time: { $gte: new Date("2023-04-22T07:30:00.000Z"), $lt: new Date("2023-04-26T13:00:00.000Z") } }, { end_time: { $gt: new Date("2023-04-22T07:30:00.000Z"), $lte: new Date("2023-04-26T13:00:00.000Z") } } ] })
修正后的查询逻辑
判断两个时间区间是否重叠的核心规则是:新时间槽的开始时间 < 已有时间槽的结束时间,且新时间槽的结束时间 > 已有时间槽的开始时间。结合指定教师ID,修正后的查询及判断逻辑如下:
// 定义要检测的新时间槽 const newStart = new Date("2023-03-22T07:30:25.787Z"); const newEnd = new Date("2023-03-22T12:30:25.787Z"); // 查询重叠的时间槽 const overlappingSlots = db.teacher.find({ id: 1276, $and: [ { start_time: { $lt: newEnd } }, { end_time: { $gt: newStart } } ] }).toArray(); // 根据结果输出判断信息 if (overlappingSlots.length > 0) { console.log(`start_time=${newStart.toISOString()},`); console.log(`end_time=${newEnd.toISOString()}`); console.log("Message=slots already available."); } else { console.log(`start_time=${newStart.toISOString()},`); console.log(`end_time=${newEnd.toISOString()}`); console.log("Message=slots not available. now you can create a slot"); }
测试用例验证
替换上述代码中的newStart和newEnd,可得到对应场景的正确结果:
场景1:新时间槽跨两个已有时间段
start_time=2023-03-22T07:30:25.787Z, end_time=2023-03-22T12:30:25.787Z Message=slots already available.
场景2:新时间槽落在第二个已有时间段内
start_time=2023-03-22T10:30:25.787Z, end_time=2023-03-22T11:30:25.787Z Message=slots already available.
场景3:新时间槽完全覆盖所有已有时间段
start_time=2023-03-22T06:30:25.787Z, end_time=2023-03-22T16:30:25.787Z Message=slots already available.
场景4:新时间槽落在第一个已有时间段内
start_time=2023-03-22T08:30:25.787Z, end_time=2023-03-22T09:30:25.787Z Message=slots already available.
场景5:新时间槽在两个已有时间段之间(无重叠)
start_time=2023-03-22T10:00:35.604Z, end_time=2023-03-22T11:00:24.787Z Message=slots not available. now you can create a slot
内容的提问来源于stack exchange,提问作者Rajesh Senapati
相关产品推荐
相关产品推荐

