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

MongoDB按日期和值分组并仅返回值发生变化记录的实现方法

实现方案

你可以使用MongoDB 5.0及以上版本提供的$setWindowFields窗口运算符实现相邻记录的字段比对,完整聚合语句如下:

let history = await History.aggregate([
  // 原有匹配逻辑
  {
    $match: {
      address: "123456",
      token_to_index: "1"
    }
  },
  // 原有按日期+价格分组逻辑
  {
    $group: {
      _id : {
        date: "$date",
        floor_price: "$stats.floor_price"
      },
      count: { $sum: 1 }
    }
  },
  // 原有按日期升序排序逻辑
  { 
    $sort: { "_id.date": 1 } 
  },
  // 新增:获取上一条记录的floor_price
  {
    $setWindowFields: {
      partitionBy: null, // 不需要分区,所有记录属于同一窗口
      sortBy: { "_id.date": 1 },
      output: {
        prev_floor_price: {
          $shift: {
            output: "$_id.floor_price",
            by: -1, // 取当前行的上一行数据
            default: null // 第一条记录的上一行默认为null
          }
        }
      }
    }
  },
  // 新增:过滤掉价格和上一条相同的记录
  {
    $match: {
      $or: [
        { prev_floor_price: null }, // 保留第一条记录
        { $expr: { $ne: [ "$prev_floor_price", "$_id.floor_price" ] } } // 保留价格变动的记录
      ]
    }
  },
  // 可选:不需要prev_floor_price字段可通过下面的阶段移除
  {
    $unset: "prev_floor_price"
  }
]);
  • $setWindowFields阶段会在排序后的结果集上开全局窗口,给每一条记录附加prev_floor_price字段存储上一条记录的floor_price值,第一条记录的该字段值为null
  • 后续的$match阶段直接过滤出第一条或者价格和上一条不一致的记录,完全等价于你写的JS过滤逻辑

如果使用的MongoDB版本低于5.0,不支持$setWindowFields运算符,无法在聚合层直接实现该逻辑,仍需要查询后通过JS代码过滤。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 09:18:04