You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js+MongoDB停车数据查询问题:无法匹配指定日期时段结果

停车查询筛选失效问题分析与修复

问题场景

我通过Postman发送以下请求,期望从MongoDB数据库中仅获取匹配条件的停车数据:

{
    "city":"Bowie",
    "startTime": "2022-07-20 10:00",
    "duration":{
        "days":"0",
        "hours":"3",
        "minutes":10
    }
}

2022年7月20日是周三,应该仅返回当天的停车可用时段,但实际返回了所有时段的完整数据:

{
  "merchantId": {
    "$oid": "62c950dfc96c2b690028be88"
  },
  "contactInfo": {
    "name": "Claudia Shields",
    "phoneNumber": 8904672101
  },
  "location": {
    "address": "737 applegate court",
    "city": "bowie",
    "state": "rhode island",
    "country": "greece",
    "zipCode": 10825
  },
  "price": 16,
  "parkingType": "residence",
  "parkingInfo": [
    {
      "parkingName": "Fountain Avenue",
      "_id": {
        "$oid": "62d12053cb03235286511d55"
      },
      "default": []
    }
  ],
  "totalSpots": [
    127
  ],
  "coordinates": {
    "lng": 34.048954,
    "lat": 10.299556
  },
  "status": "active",
  "isFeePaid": false,
  "parkingZone": [],
  "availability": [
    {
      "day": "Saturday",
      "startTime": "09:00",
      "endTime": "14:00",
      "_id": {
        "$oid": "62d13355bd1ad85d85ae4b4b"
      }
    },
    {
      "day": "Monday",
      "startTime": "08:00",
      "endTime": "16:00",
      "_id": {
        "$oid": "62d13375bd1ad85d85ae4b4f"
      }
    },
    {
      "day": "Tuesday",
      "startTime": "08:00",
      "endTime": "16:00",
      "_id": {
        "$oid": "62d1337cbd1ad85d85ae4b53"
      }
    },
    {
      "day": "Wednesday",
      "startTime": "08:00",
      "endTime": "16:00",
      "_id": {
        "$oid": "62d13383bd1ad85d85ae4b57"
      }
    },
    {
      "day": "Thursday",
      "startTime": "08:00",
      "endTime": "16:00",
      "_id": {
        "$oid": "62d13390bd1ad85d85ae4b5b"
      }
    },
    {
      "day": "Friday",
      "startTime": "08:00",
      "endTime": "16:00",
      "_id": {
        "$oid": "62d13396bd1ad85d85ae4b5f"
      }
    }
  ]
}

问题原因排查

原代码存在多个逻辑错误,导致筛选完全失效:

1. 筛选逻辑未生效

查询接口中,使用parkings.filter()但未将筛选结果赋值给变量,且直接返回了原始的parkings数组,等于完全没做筛选:

exports.getParkingListByCriteria = async (req, res) => {
  try {
    endTime = getEndTime(req.body.startTime, req.body.duration);
    console.log(`endTime: ${endTime}`);

    let parkings = await Parking.find({
      "location.city": req.body.city,
    });

    const parkingList = [];

    // filter结果未保存,且isParkingAvailable无返回值,筛选无效
    parkings.filter((parking) => {
      isParkingAvailable(parking.availability, req.body.startTime, endTime);
    });

    // 直接返回原始数据
    res.status(200).send(parkings);
  } catch (error) {
    return res.status(500).json({ error: error.message });
  }
};

2. isParkingAvailable函数核心错误

  • 星期格式不匹配:startDay是数字3(dayjs中周三对应3),但数据库中存储的是字符串"Wednesday",直接比较startDay == availabilityObject.day永远为false
  • 结束时间逻辑颠倒:availabilityObject.startTime >= endTimeOnly && availabilityObject.endTime <= endTimeOnly的判断逻辑完全错误,只有当可用时段完全被结束时间点包含时才会返回true,不符合需求
  • 无返回值:函数没有返回布尔值,导致filter无法获取判断结果
  • 变量未声明:startTimeOnly和endTimeOnly未用let/const声明,属于全局变量
exports.isParkingAvailable = (availability, startTime, endTime) => {
  let startDay = dayjs(startTime).day();
  console.log(`startDay -> ${startDay}`);
  let endDay = dayjs(endTime).day();
  console.log(`endDay -> ${endDay}`);

  let isStartAvailable = false;
  let isEndAvailable = false;

  // 未声明局部变量
  startTimeOnly = dayjs(startTime).format("HH:mm");
  console.log(`startTimeOnly -> ${startTimeOnly}`);

  endTimeOnly = dayjs(endTime).format("HH:mm");
  console.log(`endTimeOnly -> ${endTimeOnly}`);

  availability.forEach((availabilityObject) => {
    // 数字与字符串直接比较,永远不相等
    if (startDay == availabilityObject.day) {
      if (
        availabilityObject.startTime <= startTimeOnly &&
        availabilityObject.endTime >= startTimeOnly,
        console.log("availabilityObject.startTime ->",availabilityObject.startTime)
        ) {
        isStartAvailable = true;
      }
    }
    // 结束时间判断逻辑完全颠倒
    if (endDay == availabilityObject.day) {
      if (
        availabilityObject.startTime >= endTimeOnly &&
        availabilityObject.endTime <= endTimeOnly
      ) {
        isEndAvailable = true;
      }
    }
  });
  // 无返回值
};

3. 日志验证

isParkingAvailable打印的日志显示:

startDay -> 3
endDay -> 3
startTimeOnly -> 10:00
endTimeOnly -> 13:10

但数据库中availability的day字段是英文名称,导致数字与字符串无法匹配,筛选条件永远不触发。

修复方案

1. 修复isParkingAvailable函数

  • 建立星期数字与英文名称的映射关系
  • 修正结束时间判断逻辑
  • 添加布尔值返回
  • 声明局部变量
exports.isParkingAvailable = (availability, startTime, endTime) => {
  // dayjs星期映射:0=周日,1=周一,2=周二,3=周三,4=周四,5=周五,6=周六
  const dayMap = {
    0: 'Sunday',
    1: 'Monday',
    2: 'Tuesday',
    3: 'Wednesday',
    4: 'Thursday',
    5: 'Friday',
    6: 'Saturday'
  };

  const startDayName = dayMap[dayjs(startTime).day()];
  const endDayName = dayMap[dayjs(endTime).day()];
  const startTimeOnly = dayjs(startTime).format("HH:mm");
  const endTimeOnly = dayjs(endTime).format("HH:mm");

  let isAvailable = false;

  // 遍历可用时段,判断请求时间段是否完全包含在可用时段内
  for (const avail of availability) {
    // 同一天的情况(跨天逻辑可按需扩展)
    if (startDayName === avail.day && endDayName === avail.day) {
      if (avail.startTime <= startTimeOnly && avail.endTime >= endTimeOnly) {
        isAvailable = true;
        break;
      }
    }
  }

  return isAvailable;
};

2. 修复查询接口的筛选逻辑

  • 保存filter结果,返回筛选后的数组
  • 可选:进一步过滤停车记录中的availability,只保留当天的时段
exports.getParkingListByCriteria = async (req, res) => {
  try {
    const endTime = getEndTime(req.body.startTime, req.body.duration);
    console.log(`endTime: ${endTime}`);

    let parkings = await Parking.find({
      // 不区分大小写匹配城市,避免大小写问题
      "location.city": { $regex: new RegExp(req.body.city, 'i') }
    });

    // 使用filter筛选符合条件的停车记录
    const filteredParkings = parkings.filter((parking) => {
      return exports.isParkingAvailable(parking.availability, req.body.startTime, endTime);
    });

    // 可选:只保留当天的可用时段,而非全部时段
    const parkingList = filteredParkings.map(parking => {
      const dayMap = {
        0: 'Sunday',
        1: 'Monday',
        2: 'Tuesday',
        3: 'Wednesday',
        4: 'Thursday',
        5: 'Friday',
        6: 'Saturday'
      };
      const targetDay = dayMap[dayjs(req.body.startTime).day()];
      const filteredAvailability = parking.availability.filter(avail => avail.day === targetDay);
      // 转换为普通对象后修改属性
      return { ...parking.toObject(), availability: filteredAvailability };
    });

    res.status(200).send(parkingList);
  } catch (error) {
    return res.status(500).json({ error: error.message });
  }
};

额外优化建议

  • 数据库中可同时存储星期数字和名称,避免每次查询都做映射
  • 对城市查询添加不区分大小写匹配,避免因大小写差异导致的查询遗漏

内容的提问来源于stack exchange,提问作者Talc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 21:06:29