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

如何在其他函数中使用map方法返回的busId与date字段值

实现方法

你不需要做特殊的参数传递,遍历matchedBus数组时,当前遍历项的busId和date属于当前循环上下文可直接访问的变量,直接在bookings.filter回调中引用即可。以下是可直接落地的完整实现,附带常见踩坑修复:

前置查询优化(减少无效数据拉取)

查询阶段直接通过select指定返回字段,避免拉取无用字段降低性能,同时统一日期格式避免后续匹配出错:

// 先对传入的日期参数做归一化处理,避免时分秒、时区导致匹配失败
const queryDate = new Date(req.query.date);
const dayStart = new Date(queryDate.setHours(0, 0, 0, 0));
const dayEnd = new Date(queryDate.setHours(23, 59, 59, 999));

// 查询匹配出发地、目的地、日期的线路
const matchedRoutes = await Route.find({
  departureLocation: req.query.from, // 替换为你schema中实际的出发地字段名
  arrivalLocation: req.query.to, // 替换为你schema中实际的目的地字段名
  date: { $gte: dayStart, $lte: dayEnd }
})
  .select("_id busId date departureTime arrivalTime") // 只返回业务需要的字段
  .populate("busId") // 若需要返回班车详情则保留,否则可删除
  .lean(); // 转为普通JS对象,提升后续遍历操作性能

// 提取所有匹配线路ID,一次性查询关联的所有订票记录,避免循环查库产生N+1性能问题
const matchedRouteIds = matchedRoutes.map(route => route._id);
const allRelatedBookings = await Booking.find({
  routeId: { $in: matchedRouteIds }
})
  .select("routeId seats") // 只取路线关联ID和已选座位字段
  .lean();

核心过滤与座位汇总逻辑

遍历匹配线路时,直接从当前遍历项取busId和date作为过滤条件即可,不需要额外传参:

const busIdWithSeatsObj = {};

for (const route of matchedRoutes) {
  // 直接从当前线路项取需要的两个字段
  const currentBusId = route.busId._id ? route.busId._id.toString() : route.busId.toString();
  const currentDate = route.date;
  const currentRouteId = route._id.toString();

  // 过滤当前线路对应的订票记录:因为routeId和线路是一一对应关系,匹配routeId等价于匹配同班车+同日期,性能比单独匹配busId+date更高
  const currentRouteBookings = allRelatedBookings.filter(booking => {
    return booking.routeId.toString() === currentRouteId;
  });

  // 汇总当前线路所有已预订座位
  const bookedSeats = currentRouteBookings.reduce((res, booking) => {
    return res.concat(booking.seats || []);
  }, []);

  // 组装结果,用busId+日期作为唯一key,避免同班车跨日期数据覆盖
  const resultKey = `${currentBusId}_${currentDate.toISOString().slice(0, 10)}`;
  busIdWithSeatsObj[resultKey] = {
    busId: currentBusId,
    date: currentDate,
    bookedSeats: [...new Set(bookedSeats)] // 座位去重,避免异常数据导致重复
  };
}

// 最终随接口返回即可
res.json({
  success: true,
  data: {
    routeList: matchedRoutes,
    bookedSeatsMap: busIdWithSeatsObj
  }
});

常见问题修复

如果你之前过滤逻辑不生效,基本是以下三个原因:

  • ObjectId类型直接做相等判断:Mongoose返回的ID是特殊ObjectId类型,即使值相同引用不同也会判断为不相等,必须先转成字符串再比较
  • 日期匹配精度问题:如果日期字段带有时分秒,直接用===对比会因为毫秒级差异匹配失败,统一转成时间戳或者按天范围查询即可
  • 不要在循环内执行数据库查询:提前一次性拉取所有关联数据到内存中过滤,接口性能会提升数倍到数十倍不等

内容的提问来源于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 03:33:32