按名称分组,然后 select 每个名称具有最高任意字段值的一个文档

Group by name, then select one document of each name with highest arbitrary field value

假设我们有一个包含以下文档的集合:

[
    {'_id': ..., 'name': 'Type A', 'version': 1, ...},
    {'_id': ..., 'name': 'Type B', 'version': 1, ...},
    {'_id': ..., 'name': 'Type B', 'version': 2, ...},
    {'_id': ..., 'name': 'Type B', 'version': 3, ...},
    {'_id': ..., 'name': 'Type C', 'version': 1, ...},
    {'_id': ..., 'name': 'Type C', 'version': 2, ...},
    {'_id': ..., 'name': 'Type A', 'version': 2, ...},
    {'_id': ..., 'name': 'Type B', 'version': 4, ...},
    {'_id': ..., 'name': 'Type A', 'version': 3, ...},
    {'_id': ..., 'name': 'Type B', 'version': 5, ...},
]

我想要 return 一个列表,其中包含具有各自名称的最高版本的文档,这样 return 看起来像这样,本质上 returning $$具有最高版本的每个不同名称的 ROOT:

[
    {'_id': ..., 'name': 'Type A', 'version': 3, ...},
    {'_id': ..., 'name': 'Type C', 'version': 2, ...},
    {'_id': ..., 'name': 'Type B', 'version': 5, ...},
]

我知道我需要使用聚合管道,使用组排序和限制,但我似乎无法实现我想要实现的目标。

  • $sortversion 降序排列
  • $group by name 并从 grouped
  • 中获取第一个根文档
  • (可选) $replaceRootroot 对象替换为 root
pipeline = [
  { $sort: { version: -1 } },
  {
    $group: {
      _id: "$name",
      root: { $first: "$$ROOT" }
    }
  },
  { $replaceRoot: { newRoot: "$root" } }
]

result = db.collection.aggregate(pipeline)

Playground