MongoDB - 如何使用 $graphLookup,然后使用 $group,之后使用 $sort

MongoDB - How to use $graphLookup then $group and $sort after

假设我有这个数据集:

    [
        {
            _id: '1',
            name: 'test1',
            children: ['test2', so on...],
            status: 'enabled',
            version: 1,
        },
        {
            _id: '2',
            name: 'test2',
            children: [],
            status: 'enabled',
            version: 1,
        },
        {
            _id: '3',
            name: 'test2',
            children: ['test3'],
            status: 'enabled',
            version: 2,
        },
        {
            _id: '4',
            name: 'test2',
            children: [],
            status: 'disabled',
            version: 3,
        },
        {
            _id: '5',
            name: 'test3',
            children: [],
            status: 'enabled',
            version: 1,
        }
    ]

我需要做的是获取 _id=1 项的子项和 return 启用项和最高版本。

有没有办法让我通过聚合阶段简单地完成它,或者我必须通过代码手动完成?

我当前的聚合查询:

    db.Collection.aggregate([
        {
            $match: { name: 'test1', status: 'enabled' }
        },
        {
            $graphLookup: {
                from: "Collection",
                startWith: "$children",
                connectFromField: "children",
                connectToField: "name",
                as: "spreadChildren",
                restrictSearchWithMatch: {
                    status: 'enabled'
                }
            }
        }
    ])

这是预期的结果:

    [
      {
        name: 'test1',
        children: ['test2'],
        status: 'enabled',
        version: 1,
        spreadChildren: [
          {
            _id: '3',
            name: 'test2',
            children: [],
            status: 'enabled',
            version: 2,
          },
        ]
      }
    ]

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

  1. $unwind $graphLookup 结果。
  2. $sort 来自 version
  3. $groupspreadChildren.name 级别并保留所有字段;使用 $first 保留最大的 version 元素
  4. $group 再次达到 _id 级别以恢复到预期输出
db.collection.aggregate([
  {
    $match: {
      name: "test1",
      status: "enabled"
    }
  },
  {
    $graphLookup: {
      from: "collection",
      startWith: "$children",
      connectFromField: "children",
      connectToField: "name",
      as: "spreadChildren",
      restrictSearchWithMatch: {
        status: "enabled"
      }
    }
  },
  {
    "$unwind": "$spreadChildren"
  },
  {
    $sort: {
      "spreadChildren.version": -1
    }
  },
  {
    $group: {
      _id: {
        _id: "$_id",
        name: "$spreadChildren.name"
      },
      children: {
        $first: "$children"
      },
      name: {
        $first: "$name"
      },
      spreadChildren: {
        $first: "$spreadChildren"
      },
      status: {
        $first: "$status"
      },
      version: {
        $first: "$version"
      }
    }
  },
  {
    $group: {
      _id: "$_id._id",
      children: {
        $first: "$children"
      },
      name: {
        $first: "$name"
      },
      spreadChildren: {
        $push: "$spreadChildren"
      },
      status: {
        $first: "$status"
      },
      version: {
        $first: "$version"
      }
    }
  }
])

这里是Mongo playround供您参考。