You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB聚合查询结果移除外层嵌套结构的技术求助

MongoDB聚合管道:移除结果外层嵌套结构

我需要去掉聚合结果的外层嵌套结构,直接返回数据数组,但当前聚合管道最后阶段的处理方式导致使用$mergeObjects时出现“input is an array”错误,使用$concatArrays时出现“input is an object”错误。

现有聚合管道

User.aggregate([
    {
      $match: {
        "_id": userId
      }
    },
    {
      $lookup: {
        from: 'clients',
        localField: "clients",
        foreignField: "_id",
        as: "Clients",
        pipeline: [
          {
            $project: {
              "_id": 1,
              "fullName": "$fullName",
              "contracts": {"$last": "$contracts"}
            }
          },
          {
            $project: {
              "_id": 1,
              "fullName": 1,
              "contracts": {
                "type": "$contracts.contType",
                "hours": "$contracts.contHours"
              }
            }
          }
        ]
      }
    },
    {
      $lookup: {
        from: "visits",
        localField: "visits",
        foreignField: "_id",
        as: "Visits",
        pipeline: [
          {
            $match: {
              $and: [
                {"visitStart": {"$gte": new Date(start)}},
                {"visitEnd": {"$lte": new Date(end)}}
              ]
            }
          },
          {
            $project: {
              "_id": 1,
              "client": "$client",
              "hours": "$totalHours",
              "month": {
                "$month": "$visitEnd"
              },
              "year": {
                "$year": "$visitEnd"
              }
            }
          },
          {
            $project: {
              "_id": 1,
              "client": 1,
              "hours": 1,
              "date": {
                $concat: [
                  {
                    $substr: [
                      "$year",
                      0,
                      4
                    ]
                  },
                  "-",
                  {
                    $substr: [
                      "$month",
                      0,
                      2
                    ]
                  }
                ]
              }
            }
          },
          {
            $group: {
              "_id": {
                "date": "$date",
                "client": "$client"
              },
              "hoursCount": {
                $sum: "$hours"
              }
            }
          },
          {
            $group: {
              "_id": "$_id.client",
              "hours": {
                $push: {
                  "date": "$_id.date",
                  "count": "$hoursCount"
                }
              }
            }
          },
          {
            $project: {
              "_id": 0,
              "client": "$_id",
              "hours": {
                $sortArray: {"input": "$hours", "sortBy": {"date": 1}}
              }
            }
          }
        ]
      }
    },
    {
      $project: {
        "_id": 0,
        "Clients": 1,
        "Visits": 1
      }
    },
    {
      $project: {
        "result": {
          $map: {
            "input": "$Clients",
            "as": "client",
            "in": {
              $mergeObjects: [
                "$$client",
                {
                  $arrayElemAt: [
                    {
                      $filter: {
                        "input": "$Visits",
                        "as": "visits",
                        "cond": { $eq: ["$$visits.client", "$$client._id"]}
                      }
                    },
                    0
                  ]
                }
              ]
            }
          }
        } 
      }
    },
])

当前返回结果

[
    {
        "result": [
            {
                "_id": "6205a8313fe12d6b4ec354c4",
                "fullName": "Johnny Cochrane",
                "contracts": {
                    "type": "Quarterly",
                    "hours": 120
                },
                "client": "6205a8313fe12d6b4ec354c4",
                "hours": [
                    {
                        "date": "2023-4",
                        "count": 5.51
                    },
                    {
                        "date": "2023-5",
                        "count": 6
                    },
                    {
                        "date": "2023-6",
                        "count": 2
                    }
                ]
            },
            {
                "_id": "6217c1b73fe12d6b4ec3550e",
                "fullName": "Sheila Thompson",
                "contracts": {
                    "type": "Quarterly",
                    "hours": 140
                },
                "client": "6217c1b73fe12d6b4ec3550e",
                "hours": [
                    {
                        "date": "2023-4",
                        "count": 5.5
                    },
                    {
                        "date": "2023-5",
                        "count": 4
                    },
                    {
                        "date": "2023-6",
                        "count": 2
                    }
                ]
            }
        ]
    }
]

尝试过的无效阶段

{
      $replaceRoot: {
        newRoot: {
          $mergeObjects: [
            "$$ROOT",
            "$result"
          ]
        }
      }
}

期望结果

[
    {
        "_id": "6205a8313fe12d6b4ec354c4",
        "fullName": "Johnny Cochrane",
        "contracts": {
            "type": "Quarterly",
            "hours": 120
        },
        "client": "6205a8313fe12d6b4ec354c4",
        "hours": [
            {
                "date": "2023-4",
                "count": 5.51
            },
            {
                "date": "2023-5",
                "count": 6
            },
            {
                "date": "2023-6",
                "count": 2
            }
        ]
    },
    {
        "_id": "6217c1b73fe12d6b4ec3550e",
        "fullName": "Sheila Thompson",
        "contracts": {
            "type": "Quarterly",
            "hours": 140
        },
        "client": "6217c1b73fe12d6b4ec3550e",
        "hours": [
            {
                "date": "2023-4",
                "count": 5.5
            },
            {
                "date": "2023-5",
                "count": 4
            },
            {
                "date": "2023-6",
                "count": 2
            }
        ]
    }
]

解决方案

在现有聚合管道的末尾添加以下两个阶段即可实现需求:

// 展开result数组,将数组中的每个元素转为独立文档
{ $unwind: "$result" },
// 将每个文档的根替换为result中的对象
{ $replaceRoot: { newRoot: "$result" } }

原错误的原因是$result是数组类型,$mergeObjects只能处理对象,无法直接合并数组和对象。通过$unwind将数组拆分为多个单文档后,再用$replaceRoot把每个文档的内容替换为目标对象,就能得到你想要的纯数组结果。

内容的提问来源于stack exchange,提问作者Jowz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 03:37:06