MongoDB 聚合管道 - 获取最旧的文档,但去抖动

MongoDB Aggregation Pipeline - get oldest document, but debounced

我的文件看起来像:

[ 
  { 
    value: 'Apple',
    createdAt: '2021-12-09T20:15:26.421+00:00',
  },
  { 
    value: 'Blueberry',
    createdAt: '2021-12-09T20:45:26.421+00:00',
  },
  { 
    value: 'Cranberry',
    createdAt: '2021-12-09T21:30:26.421+00:00',
  },
  { 
    value: 'Durian',
    createdAt: '2022-01-24T20:15:26.421+00:00',
  },
  { 
    value: 'Elderberry',
    createdAt: '2022-01-24T20:45:26.421+00:00',
  },
]

我想在获取最旧文档的地方进行聚合,但需要注意的是,如果在一个小时内创建了另一个文档,它会使第一个文档失效,而我实际上想获取那个文档。比如在上面我想returnCranberry。最初选择 Apple,但由于 Blueberry 在一小时内出现,因此移动到那个,并且由于 CranberryBlueberry、select 的一小时内出现 Cranberry.

您可以在聚合管道中执行以下操作:

  1. $sort 来自 createdAt
  2. $limit获取最早的文档
  3. $lookup获取当前文档
  4. 后面所有createdAt的文档
  5. $reduce循环结果数组;仅当当前条目在 1 小时内更新 accumulator/result
db.collection.aggregate([
  {
    $sort: {
      createdAt: 1
    }
  },
  {
    $limit: 1
  },
  {
    "$lookup": {
      "from": "collection",
      let: {
        current: "$createdAt"
      },
      pipeline: [
        {
          $match: {
            $expr: {
              $gte: [
                "$createdAt",
                "$$current"
              ]
            }
          }
        }
      ],
      "as": "within"
    }
  },
  {
    "$addFields": {
      "within": {
        "$reduce": {
          "input": "$within",
          "initialValue": null,
          "in": {
            "$cond": {
              "if": {
                $or: [
                  {
                    $eq: [
                      "$$value",
                      null
                    ]
                  },
                  {
                    $lte: [
                      {
                        "$subtract": [
                          "$$this.createdAt",
                          "$$value.createdAt"
                        ]
                      },
                      3600000
                    ]
                  }
                ]
              },
              "then": "$$this",
              "else": "$$value"
            }
          }
        }
      }
    }
  }
])

这里是Mongo playground供大家参考。