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

MongoDB字符串字段查询能否同时使用$regex与$gte/$lte操作符

报错原因
  • 类型不匹配:$gte、$lte是值比较操作符,仅支持传入字符串、数值、Date类型的对比值,你向操作符内传入了{$regex: ...}的正则对象,和Schema中Trandate定义的String类型不匹配,触发类型转换错误。
  • 重复键覆盖:JS对象不允许存在同名键,你在查询条件中写了两次Trandate,后定义的{$lte: ...}会覆盖之前的{$gte: ...},导致查询条件缺失。
  • 格式逻辑错误:你用hi-IN区域的toLocaleDateString输出的是日/月/年格式,和库中存储的月/日/年格式不匹配,即使没有类型错误也无法匹配到正确数据;且M/D/YYYY格式的字符串直接做字典序大小比较会出现乱序问题(如10/1/2021 < 2/1/2021),无法得到正确的区间结果。
正确实现方案

方案1:修改存储类型(推荐)

将Trandate字段从字符串类型改为MongoDB原生Date类型,既可以避免格式转换问题,查询性能也远高于字符串匹配:

// 结束日期设置为当天最后一毫秒,避免遗漏结束日期当天的记录
const start = new Date(FromDate);
const end = new Date(ToDate);
end.setHours(23, 59, 59, 999);

const chooseWinner = await Transaction.find(
  {
    ContCode: CountryCode,
    CurrCode: CurrCode,
    CorrOrgCode: CorrorgCode,
    ServCode: ServCode,
    BranchCode: BranchCode,
    Trandate: {$gte: start, $lte: end}
  },
  "CustomerCode ReferenceNo Trandate "
);

方案2:不改现有存储结构

如果无法修改历史存储格式,使用聚合管道将字符串转成Date类型后再做区间过滤:

const chooseWinner = await Transaction.aggregate([
  // 先过滤非日期条件,缩小扫描范围
  {$match: {
    ContCode: CountryCode,
    CurrCode: CurrCode,
    CorrOrgCode: CorrorgCode,
    ServCode: ServCode,
    BranchCode: BranchCode
  }},
  // 把字符串格式的Trandate转成Date类型
  {$addFields: {
    TrandateDate: {
      $dateFromString: {
        dateString: "$Trandate",
        format: "%m/%d/%Y %H:%M:%S %p"
      }
    }
  }},
  // 日期区间过滤
  {$match: {
    TrandateDate: {
      $gte: new Date(FromDate),
      $lte: new Date(new Date(ToDate).setHours(23,59,59,999))
    }
  }},
  // 输出指定字段
  {$project: {
    CustomerCode: 1,
    ReferenceNo: 1,
    Trandate: 1,
    _id: 0
  }}
])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 14:39:04