MongoDB多条件查询:实现城市与停车可用日期联合筛选
实现方案
你现有代码已经实现了地理位置字段的模糊匹配,要加上「城市+日期同时满足才返回」的逻辑,只需要补充日期参数处理、追加日期匹配条件即可,另外顺便修正原有代码中正则参数的写法bug。
核心调整点
- 新增日期入参读取,补全必填参数校验
- 统一处理日期类型:因为库中
availability.date是Date类型,直接用字符串匹配会因为类型不一致失效,同时要避免时分秒、时区偏差导致漏匹配,统一取查询日期的当日0点到次日0点作为时间区间 - 将日期匹配条件和地理位置条件并列传入查询(MongoDB多字段默认就是AND关系,不需要额外包
$and数组,可读性更好) - 省、国家字段如果是可选筛选项,做传值判断,没传值时不追加对应过滤条件
- 修正原有代码中正则选项的错误写法:原代码里
($options = "i")是赋值表达式,直接给RegExp构造函数传第二个参数为"i"即可
调整后可直接运行的代码
exports.getParkingListByCriteria = async (req, res) => { const cityQuery = req.body.city; const stateQuery = req.body.state; const countryQuery = req.body.country; // 读取前端传入的查询日期,约定格式为YYYY-MM-DD字符串 const queryDate = req.body.queryDate; // 必填参数校验 if (!cityQuery || !queryDate) { return res.status(400).json({ error: "城市、查询日期为必填项" }); } try { // 构造当日时间区间,解决Date类型时分秒、时区匹配偏差问题 const targetDate = new Date(queryDate); const startOfDay = new Date(targetDate.setHours(0, 0, 0, 0)); const endOfDay = new Date(targetDate.setHours(24, 0, 0, 0)); const parkingList = await Parking.find({ "location.city": { $regex: new RegExp(cityQuery, "i") }, // 可选参数:有传值才加过滤规则 ...(stateQuery ? { "location.state": { $regex: new RegExp(stateQuery, "i") } } : {}), ...(countryQuery ? { "location.country": { $regex: new RegExp(countryQuery, "i") } } : {}), // 匹配availability数组中存在查询当日可用记录的停车场 "availability.date": { $gte: startOfDay, $lt: endOfDay } }); res.status(200).send(parkingList); } catch (error) { return res.status(500).json({ error: error.message }); } };
扩展说明
如果后续需要同时校验「日期+所选时段是否可用」,不能直接用点路径匹配,需要用$elemMatch确保日期、开始时间、结束时间三个条件命中的是同一条可用记录,示例写法:
// 同时匹配日期+可用时段的条件片段 availability: { $elemMatch: { date: { $gte: startOfDay, $lt: endOfDay }, startTime: { $lte: req.body.userStartTime }, // 用户选择的入场时间要晚于可用开始时间 endTime: { $gte: req.body.userEndTime } // 用户选择的离场时间要早于可用结束时间 } }
内容的提问来源于stack exchange,提问作者Talc
相关产品推荐
相关产品推荐

