MongoDB 聚合:仅保留分区中最后一项的运行总计

问题描述 投票:0回答:1

我有这样的数据:

[
  { "grp": "A", "seq": 1, "score": 1, x: 0 },
  { "grp": "A", "seq": 1, "score": 2, x: 0 },
  { "grp": "A", "seq": 1, "score": 3, x: 0 },
  { "grp": "A", "seq": 1, "score": 4, x: 0 }
]

使用

$setWindowFields

{
  partitionBy: "$grp",
  sortBy: { seq: 1 },
  output: {
    x: {
      $sum: "$score",
      window: {
        documents: ["unbounded", "current"]
      }
    },
  }
}

我得到:

[
  { "grp": "A", "seq": 1, "score": 1, x: 1 },
  { "grp": "A", "seq": 1, "score": 2, x: 3 },
  { "grp": "A", "seq": 1, "score": 3, x: 6 },
  { "grp": "A", "seq": 1, "score": 4, x: 10 }
]

我只需要保留分区的

最后一项
的运行总和(x)。

[
  { "grp": "A", "seq": 1, "score": 1, x: 0 },
  { "grp": "A", "seq": 1, "score": 2, x: 0 },
  { "grp": "A", "seq": 1, "score": 3, x: 0 },
  { "grp": "A", "seq": 1, "score": 4, x: 10 }
]

我一直在使用

$project
$last
进行测试,但我无法使其工作。

我需要使用什么更好的表达或额外的阶段?

谢谢!

mongodb aggregation-framework
1个回答
0
投票

不确定您的数据集中是否存在确定性排序,但使用与您使用的相同排序,您可以在

ordering
中将
$documentNumber
$setWindowFields
一起分配。然后,使用
$rank
字段计算
ordering
。最后一个文档将有
rank: 1
。您可以将其与
$cond
一起使用来有条件地设置字段
x

db.collection.aggregate([
  {
    "$setWindowFields": {
      partitionBy: "$grp",
      sortBy: {
        seq: 1
      },
      output: {
        x: {
          $sum: "$score",
          window: {
            documents: [
              "unbounded",
              "current"
            ]
          }
        },
        ordering: {
          $documentNumber: {}
        }
      }
    }
  },
  {
    "$setWindowFields": {
      "partitionBy": "$grp",
      "sortBy": {
        "ordering": -1
      },
      "output": {
        "rank": {
          "$rank": {}
        }
      }
    }
  },
  {
    "$set": {
      "ordering": "$$REMOVE",
      "rank": "$$REMOVE",
      "x": {
        "$cond": {
          "if": {
            $eq: [
              1,
              "$rank"
            ]
          },
          "then": "$x",
          "else": 0
        }
      }
    }
  }
])

蒙戈游乐场

© www.soinside.com 2019 - 2024. All rights reserved.