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

如何用Mongoose获取指定站点最近7天的detections数据?

MongoDB筛选嵌套数组中最近7天数据的方案

前提说明

你的示例中datetime字段只有时间(如"05:00 pm"),没有日期信息,这样根本没法筛选「最近7天」的数据。请务必确保datetime存储为完整的日期时间格式——推荐用MongoDB原生的ISODate类型,或者带日期的标准字符串(如"2024-05-20 17:00:00"),以下所有方案默认datetime是可用于日期比较的合法格式。

方案一:使用Aggregate管道(最灵活)

用聚合管道可以精准控制数组过滤逻辑,步骤清晰:

  1. 先匹配目标站点,缩小处理范围
  2. 重新生成detections数组,只保留符合时间条件的元素

代码示例:

// 计算7天前的时间戳
const sevenDaysAgo = new Date();
sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);

const siteResult = await SiteModel.aggregate([
  // 第一步:定位目标站点
  { $match: { _id: mongoose.Types.ObjectId(siteID) } },
  // 第二步:过滤detections数组
  {
    $addFields: {
      detections: {
        $filter: {
          input: "$detections",
          cond: {
            // 判断元素的datetime是否晚于7天前
            $gte: ["$$this.datetime", sevenDaysAgo]
          }
        }
      }
    }
  }
]);

// aggregate返回数组,取第一个元素即为目标站点
const targetSite = siteResult[0];

如果你的datetime是字符串格式,需要先转成Date类型再比较,将cond修改为:

cond: {
  $gte: [{ $toDate: "$$this.datetime" }, sevenDaysAgo]
}

方案二:使用find投影(更简洁)

如果不需要复杂聚合操作,直接在find查询的投影里用$filter也能实现,代码更简短:

const sevenDaysAgo = new Date();
sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);

const targetSite = await SiteModel.findById(siteID, {
  // 保留你需要的其他字段
  name: 1,
  timezone: 1,
  location: 1,
  // 过滤detections数组
  detections: {
    $filter: {
      input: "$detections",
      cond: { $gte: ["$$this.datetime", sevenDaysAgo] }
    }
  }
});

额外提示

  • 若数据量较大,给detections.datetime字段加索引能显著提升查询速度
  • 测试时可以先打印sevenDaysAgo的值,确认时间范围正确
  • 字符串格式的datetime一定要转成Date类型再比较,否则会按字符串字典序排序,导致筛选结果错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 00:30:55