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

Mongoose聚合查询递归函数按ID搜索失效问题排查

Mongoose聚合查询中参数传入ID不生效的问题排查与修复

问题分析

看你代码里的这行关键查询条件:

{"_line._id": '"' + line_id.toString() + '"'}

问题就出在你给line_id额外拼接了双引号!

当你直接手动传入ID字符串(比如5a01e1dbaf371d00152eae89)时,你其实是在使用不带额外双引号的正确值去匹配数据库里的_id;但通过参数line_id传入时,你把它拼接成了带双引号的字符串(比如"5a01e1dbaf371d00152eae89"),而数据库里的_id要么是ObjectID类型,要么是纯字符串类型(不带引号),自然匹配不到任何数据。

另外还有个小细节:如果line_id本身是Mongoose的ObjectID对象,toString()会返回不带引号的纯ID字符串,你额外加的双引号完全是多余的,反而破坏了匹配逻辑。

修复方案

  1. 移除多余的双引号拼接,直接使用转换后的ID值;
  2. 确保ID类型匹配:如果数据库里_line._id是ObjectID类型,最好把参数转换为ObjectID(避免字符串匹配的潜在问题)。

这里给你修改后的核心代码部分,以及优化后的moment日期处理:

function getTripsLocation(line_id, index) {
  console.log(line_id);
  // 把line_id转换为ObjectID(如果你的_line._id是ObjectID类型)
  const targetLineId = typeof line_id === 'string' ? mongoose.Types.ObjectId(line_id) : line_id;
  
  trip.aggregate([
    {
      $match: {
        $and: [
          {"_line._id": targetLineId}, // 去掉多余双引号,用正确的ID值
          {
            "createdAt": {
              // 简化moment日期处理,直接用moment的方法生成Date对象
              $gte: moment().subtract(1, 'days').startOf('day').toDate(),
              $lte: moment().subtract(1, 'days').endOf('day').toDate()
            }
          }
        ],
      }
    },
    {
      $lookup: {
        from: "locations",
        localField: "_id",
        foreignField: "trip_id",
        as: "local",
      },
    }
  ])
  .then((data) => {
    // 后续逻辑保持不变
    if (data) {
      console.log(index, allLines[index]._id, moment().subtract(1, 'days').format('YYYY-MM-DD 00:00:00'));
      index++;
      if (index > allLines.length - 1) {
        finishProcess('Finish Task . . .');
      } else {
        console.log(data);
        setTimeout(() => {
          if (data.length > 0) {
            timeDifferenceCalculation(line_id, data,index);
          } else {
            getTripsLocation(allLines[index]._id,index);
          }
        }, 1)
      }
    }
  })
  .catch((err) => console.log('catch_error_on_trips', err));
}

额外说明

  • 如果你的_line._id存储的是纯字符串类型,那可以不用转换为ObjectID,直接用line_id.toString()(注意不要加双引号)即可;
  • 用moment().startOf('day')和endOf('day')比手动格式化字符串再转Date更可靠,也更简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:56:01