【问题标题】:$lookup in nested array$查找嵌套数组
【发布时间】:2021-02-11 16:57:31
【问题描述】:

我需要一个 MongoDB 查询来返回来自事件、用户和确认集合的聚合结果。

db.events.aggregate([
  {
    "$match": {
      "_id": "1"
    }
  },
  {
    "$lookup": {
      "from": "confirmations",
      "as": "confirmations",
      "let": {
        "eventId": "$_id"
      },
      "pipeline": [
        {
          "$match": {
            "$expr": {
              "$eq": [
                "$eventId",
                "$$eventId"
              ]
            }
          }
        },
        {
          "$lookup": {
            "from": "users",
            "as": "user",
            "let": {
              "userId": "$confirmations.userId"
            },
            "pipeline": [
              {
                "$match": {
                  "$expr": {
                    "$eq": [
                      "$_id",
                      "$$userId"
                    ]
                  }
                }
              },
              
            ]
          },
          
        },
        
      ]
    }
  }
])

想要的

[
  {
    "_id": "1",
    "confirmations": [
      {
        "_id": "1",
        "eventId": "1",
        "user": {
          "_id": "1",
          "name": "X"
        },
        "userId": "1"
      },
      {
        "_id": "2",
        "eventId": "1",
        "user": {
          "_id": "2",
          "name": "Y"
        },
        "userId": "2"
      }
    ],
    "title": "foo"
  }
]

除了确认数组中的嵌入式用户外,一切正常。我需要输出显示确认用户,而不是空数组。

游乐场:https://mongoplayground.net/p/jp49FW59WCv

【问题讨论】:

  • 看到这个playground你只需要更正用户的$lookup并添加$unwind
  • 谢谢...虽然这是一个人为的例子。我很好奇如何使用嵌套的 $lookup 管道来解决。

标签: mongodb mongodb-query aggregation-framework


【解决方案1】:

您在内部$lookup 的变量声明中犯了错误。试试这个解决方案:

db.events.aggregate([
    {
        "$match": {
            "_id": "1"
        }
    },
    {
        $lookup: {
            from: "confirmations",
            let: { "eventId": "$_id" },
            pipeline: [
                {
                    $match: {
                        "$expr": {
                            $eq: ["$eventId", "$$eventId"]
                        }
                    }
                },
                {
                    $lookup: {
                        from: "users",
                        let: { "userId": "$userId" },
                        pipeline: [
                            {
                                $match: {
                                    $expr: {
                                        $eq: ["$_id", "$$userId"]
                                    }
                                }
                            }
                        ],
                        as: "user"
                    }
                },
                { $unwind: "$user" }
            ],
            as: "confirmations"
        }
    }
])

您也可以使用内部$lookup 中的$unwind 来代替user 中的$unwind

{
    $addFields: {
        user: { $arrayElemAt: ["$user", 0] }
    }
}

因为$unwind 默认不会保留前一阶段的空结果。

【讨论】:

  • ? 有道理...对于 $lookup 阶段的 let 分配,不需要 $confirmations,因为它已经假定为与 $userId 相关的范围内的集合。
猜你喜欢
  • 2015-06-20
  • 2013-06-17
  • 1970-01-01
  • 1970-01-01
  • 2013-10-11
  • 2019-08-15
  • 2019-03-16
  • 2022-11-11
  • 2023-02-01
相关资源
最近更新 更多