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字符串,你额外加的双引号完全是多余的,反而破坏了匹配逻辑。
修复方案
- 移除多余的双引号拼接,直接使用转换后的ID值;
- 确保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
相关产品推荐
相关产品推荐

