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

如何用Mongoose Aggregate实现$gte和$lte日期范围查询?

问题

使用Mongoose 5.11.15查询数据时,find方法结合$and、$gte、$lte条件可以正常获取test_id匹配且createdAt在指定日期范围内的数据,但改用aggregate的$match阶段时,却无法返回任何数据——仅保留test_id条件时能正常查询。

原find方法代码

let datas = await Data.find({
  '$and': [
    { test_id: testId },
    { createdAt: { $gte: moment(req.query.from).startOf('day') } },
    { createdAt: { $lte: moment(req.query.to).endOf('day') } }
  ],
});

尝试的aggregate代码

const datas = await Data.aggregate([
  {
    '$match': {
      '$and': [
        { test_id: testId },
        { createdAt: { $gte: moment(req.query.from).startOf('day') } },
        { createdAt: { $lte: moment(req.query.to).endOf('day') } }
      ],
    }
  }
]);

Schema定义

const Data = new Schema({
  test_id: {
    type: String,
    required: true,
  },
  user_id: {
    type: String,
    required: true,
  },
  item: {
    agent_id: { type: String, ref: 'Company' },
    product_no: { type: String, required: true },
    user_id: { type: String, required: true, ref: 'User' },
    name: { type: String, required: true },
    quantity: { type: Number, required: true },
    standard_price: { type: Number},
    designation: { type: String },
    category: { type: String },
    weight: { type: Number },
    materials: { type: String },
    remarks: { type: String },
    note: { type: String },
    location: String,
    image: String
  }
}, {
  timestamps: true,
});

解决方案

问题出在aggregate的$match阶段中,$and数组里重复定义了createdAt字段。MongoDB的查询文档不允许同一个键在一个对象中重复出现,后定义的键会覆盖前一个,导致实际生效的条件只有单个范围限制,自然查不到符合日期区间的数据。而find方法中Mongoose会自动帮你合并同一个字段的多个条件,所以能正常工作。

修改方法是将createdAt的$gte和$lte条件合并到同一个对象中,同时$and可以省略(MongoDB默认多个条件就是逻辑与的关系):

const datas = await Data.aggregate([
  {
    '$match': {
      test_id: testId,
      createdAt: {
        $gte: moment(req.query.from).startOf('day'),
        $lte: moment(req.query.to).endOf('day')
      }
    }
  }
]);

如果一定要保留$and写法,也需要把createdAt的条件合并:

const datas = await Data.aggregate([
  {
    '$match': {
      '$and': [
        { test_id: testId },
        { 
          createdAt: {
            $gte: moment(req.query.from).startOf('day'),
            $lte: moment(req.query.to).endOf('day')
          }
        }
      ]
    }
  }
]);

这样修改后,aggregate的查询逻辑就和find方法完全一致,能正确返回符合条件的数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 13:36:30