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

Node.js使用Mongoose查询仅返回巴士数据 无法获取座位预订数据

问题根因

代码里4处逻辑错误直接导致座位数据返回空:

  • 无效的matchedBus筛选:routes.filter()的判断逻辑里,Route.busId是模型层不存在的属性(值为undefined),routes._id是数组对象不存在的属性(值也为undefined),两边全等永远为true,相当于把所有查询到的routes原样返回,属于完全冗余的无效代码,而且filter是数组同步方法,前面加await没有任何作用。
  • Booking匹配字段写错:对照你的Booking Schema,顶层根本没有date和busId两个字段:行程日期存储在departureDetails数组的date属性下,巴士信息是通过routeId关联Route表、再通过Route表的busId关联巴士表拿到的,直接用booking.date、booking.busId做匹配永远拿不到结果。
  • ObjectId对比逻辑错误:Mongoose查询返回的文档ID是ObjectId类型对象,不是普通字符串,直接用===做全等对比会返回false,需要转成字符串或者用Mongoose自带的equals()方法对比。
  • 座位数据引用错误:遍历booking记录取座位时,你写的...Booking.seats是引用整个Booking模型的seats属性,不是当前遍历到的单条订票记录的seats字段,就算前面匹配到了订票数据,这里也拿不到正确的座位号。
修复后代码

直接替换原有接口逻辑即可,修复了上述所有问题,同时加了populate关联查询直接带出巴士基础信息(比如总座位数),方便后续计算可用座位:

router.get("/trip/single", async (req, res) => {
  if (!req.query.from || !req.query.to || !req.query.date) {
    return res.send({
      error: "Please enter the data to get the trip",
    });
  }
  const { from, to, date } = req.query;
  const targetDate = date.toString();

  // 查询匹配的线路,同时关联带出对应巴士的基础信息
  const routes = await Route.find({
    "Location.from": from,
    "Location.to": to,
    "date": targetDate,
  }).populate("busId");

  // 批量查询对应线路下的所有订票记录,直接在数据库层过滤日期减少内存运算
  const routeIds = routes.map(route => route._id);
  const bookings = await Booking.find({
    routeId: { $in: routeIds },
    "departureDetails.date": targetDate
  });

  const bookedSeatsByBus = {};
  
  for (const route of routes) {
    const currentBusId = route.busId._id.toString();
    let bookedSeats = [];

    // 筛选当前线路对应的所有订票记录,用equals对比ObjectId避免类型问题
    const currentRouteBookings = bookings.filter(booking => booking.routeId.equals(route._id));

    // 合并所有订票记录的已选座位
    currentRouteBookings.forEach(booking => {
      bookedSeats.push(...booking.seats);
    });

    // 座位号去重,避免异常数据导致重复统计
    bookedSeatsByBus[currentBusId] = [...new Set(bookedSeats)];
  }

  res.status(200).send({ 
    routes, 
    bookedSeatsByBus
    // 后续计算可用座位:拿populate返回的巴士总座位数生成全量座位数组,过滤掉已订座位即可
  });
});
优化建议
  • 建议把所有日期字段从String类型改成Mongoose的Date类型,后续做日期范围查询、时区转换时可以避免很多格式兼容问题。
  • 如果数据量较大,可以直接用MongoDB的聚合框架一次性完成关联、分组统计座位的操作,比多次查询+内存筛选的性能高很多。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 07:21:55