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

Node.js结合Mongoose使用MongoDB $in操作符查询返回空数组的问题

问题分析与解决方案

我帮你排查了几个关键问题,这些应该就是导致查询返回空数组的核心原因:


1. 查询日期范围与目标数据不匹配

看你提供的调用参数,查询的targetDate范围是2021-03-03 到 2021-03-31,但你给出的示例数据里targetDate是2021-04-06T14:30:00.000Z,这个日期完全不在你设定的查询区间内!这是最直接的原因——你的目标数据根本不在查询时间范围内,自然返回空数组。

解决方法:
检查调用参数里的fromTime和toTime是否正确,确保时间范围覆盖你要查询的数据日期。比如如果要包含示例数据的4月6日,需要把toTime调整到2021-04-07T18:29:59.000Z之后。


2. 错误使用Schema而非Model执行查询

在你的getGeofenceReport函数里,你写了:

GeofenceReportSchema.find(queryObj)

但GeofenceReportSchema是mongoose的Schema结构定义对象,不是可直接用于查询的模型实例。你应该使用你导出的model(也就是GeofenceReport)来调用find方法。

解决方法:
先确保已经正确导入模型:

const GeofenceReport = require('./path-to-your-model-file');

然后把查询代码改成:

GeofenceReport.find(queryObj)

3. IMEI的数组格式与类型优化

数组格式问题

你的调用参数里imei是单个数字866551038558000,如果queryItems.imei不是数组,$in操作符里就会传入单个值——虽然MongoDB允许这种写法,但为了避免潜在的类型错误,最好强制转换成数组:

const imeiList = Array.isArray(queryItems.imei) ? queryItems.imei : [queryItems.imei];
const queryObj = {
  $and: [
    {targetDate: { $gte: new Date(queryItems.fromTime), $lte: new Date(queryItems.toTime)}},
    {imei: {$in: imeiList}}
  ]
};

数值精度问题

你的示例数据里IMEI存储的是$numberLong类型,而Mongoose模型里定义的是Number。虽然当前的IMEI数值小于JSNumber的最大安全值(2^53),但IMEI作为标识号不需要做数值运算,更稳妥的做法是把它定义为String类型:

imei: { type: String, required: true },

这样可以彻底避免数值转换带来的精度丢失或类型匹配问题,查询时也要确保传入的IMEI是字符串类型。


额外排查建议

  • 查询前可以分别打印完整的queryObj和数据里的targetDate、imei值,对比确认条件是否匹配;
  • 可以拆分查询条件,单独测试日期查询或IMEI查询,分步定位哪个条件出了问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 12:37:33