如何使用MongoDB聚合判断当前时间是否在法语标注的餐厅营业时间内
MongoDB 聚合判断餐厅营业状态方案
首先明确法语星期与Date对象返回星期序号的映射关系:
- 0 → Dimanche(周日)
- 1 → Lundi(周一)
- 2 → Mardi(周二)
- 3 → Mercredi(周三)
- 4 → Jeudi(周四)
- 5 → Vendredi(周五)
- 6 → Samedi(周六)
完整聚合查询代码
const now = new Date(); // 法语星期映射表 const weekMap = ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi']; const currentWeekDay = weekMap[now.getDay()]; // 将当前时间转为4位数字方便比较,例如08:30转为830、22:15转为2215 const currentTime = now.getHours() * 100 + now.getMinutes(); db.restaurants.aggregate([ { $addFields: { // 取出当日对应营业时间区间 currentHours: `$hours.${currentWeekDay}`, // 转换开门时间为数字格式 openTime: { $let: { vars: { timeArr: { $split: [ { $first: `$hours.${currentWeekDay}` }, ':' ] } }, in: { $add: [ { $multiply: [ { $toInt: { $arrayElemAt: [ "$$timeArr", 0 ] } }, 100 ] }, { $toInt: { $arrayElemAt: [ "$$timeArr", 1 ] } } ] } } }, // 转换关门时间为数字格式 closeTime: { $let: { vars: { timeArr: { $split: [ { $last: `$hours.${currentWeekDay}` }, ':' ] } }, in: { $add: [ { $multiply: [ { $toInt: { $arrayElemAt: [ "$$timeArr", 0 ] } }, 100 ] }, { $toInt: { $arrayElemAt: [ "$$timeArr", 1 ] } } ] } } }, // 计算营业状态 isOpen: { $and: [ { $gte: [ currentTime, "$openTime" ] }, { $lte: [ currentTime, "$closeTime" ] } ] } } }, // 可选:仅过滤当前营业的餐厅 { $match: { isOpen: true } } ])
特殊场景适配
- 跨天营业:如果存在营业时间跨次日的场景(例如22:00~次日02:00),将
isOpen的判断逻辑修改为{ $or: [ { $gte: [ currentTime, "$openTime" ] }, { $lte: [ currentTime, "$closeTime" ] } ] }即可 - 歇业场景:如果餐厅当日歇业对应星期字段为空数组,在
isOpen的判断条件中新增{ $gt: [ { $size: "$currentHours" }, 0 ] }即可 - 时区适配:如果服务端和数据库时区不一致,可以替换为MongoDB内置的
$dateToString操作符在数据库侧计算当前时间和星期,避免时区偏差
内容的提问来源于stack exchange,提问作者Mehdi Khlifi
相关产品推荐
相关产品推荐

