如何 promote/pull 子字段在 mongo 聚合管道中向上一级

How to promote/pull a child field up one level in mongo aggregation pipeline

我有一个看起来像这样的集合:

[
  {
    _id: ObjectId("6255a889fb63822bd51b0356"),
    answers: {
      "6255a889fb63822bd51b0326": {
        value: ObjectId("6255a889fb63822bd51b0329"),
        
      },
      "6255a889fb63822bd51b032a": {
        value: [
          ObjectId("6255a889fb63822bd51b0321"),
          ObjectId("6255a889fb63822bd51b032d")
        ],
        
      },
      "6255a889fb63822bd51b032e": {
        value: 2,
        comment: "hello",
        
      }
    },
    createdAt: ISODate("2022-03-12T17:27:53.890Z")
  }
]

我从

开始我的管道
{
  $project: {
     _id: 0,
     answers: { $objectToArray: "$answers" },
     date: { $dateToString: { format: dateFormat, date: "$createdAt" } },
   },
},

得到这样的结果:

[
  {
    answers: [
      {
        k: '6255a9a60fd8f862f4bd287f',
        v: {
          value: new ObjectId("6255a9a60fd8f862f4bd2882"),
          _id: new ObjectId("6255a9a60fd8f862f4bd28b2")
        }
      },
      {
        k: '6255a9a60fd8f862f4bd2883',
        v: {
          value: [
            new ObjectId("6255a9a60fd8f862f4bd287a"),
            new ObjectId("6255a9a60fd8f862f4bd2886")
          ],
          _id: new ObjectId("6255a9a60fd8f862f4bd28b3")
        }
      },
      {
        k: '6255a9a60fd8f862f4bd2887',
        v: {
          value: 2,
          comment: 'hello',
          _id: new ObjectId("6255a9a60fd8f862f4bd28b4")
        }
      }
    ],
    date: '2022-03-12'
  }
]

我想拉起 value 并将 v 替换为 value 所以我最终得到如下所示的结果。我在想也许在 $objectToArray 的第一步中有一些方法可以做到这一点?或者之后我还需要另一个步骤吗?

[
  {
    answers: [
      {
        k: '6255a9a60fd8f862f4bd287f',
        v: new ObjectId("6255a9a60fd8f862f4bd2882")
      },
      {
        k: '6255a9a60fd8f862f4bd2883',
        v: [
            new ObjectId("6255a9a60fd8f862f4bd287a"),
            new ObjectId("6255a9a60fd8f862f4bd2886")
          ]
      },
      {
        k: '6255a9a60fd8f862f4bd2887',
        v: 2
      }
    ],
    date: '2022-03-12'
  }
]

您只需要再 $map 即可获得您想要的形式。

db.collection.aggregate([
  {
    $project: {
      _id: 0,
      answers: {
        "$map": {
          "input": {
            $objectToArray: "$answers"
          },
          "as": "a",
          "in": {
            k: "$$a.k",
            v: "$$a.v.value"
          }
        }
      },
      date: {
        $dateToString: {
          format: "%Y-%m-%d",
          date: "$createdAt"
        }
      }
    }
  }
])

这是Mongo playground供您参考。