【问题标题】:How can I do a lookup based on conditional selection?如何根据条件选择进行查找?
【发布时间】:2019-08-06 02:32:26
【问题描述】:

我有 2 个基于 collection1 的集合,我需要从 collection2 中获取

集合1

 [
    {
      "_id": ObjectId("5ce7454f77af2d1143f84c38"),
      "menu_name": "mainmenu1",
      "sub_menus": [
        {
          "name": "submenu1",
          "project": [
            "All"
          ]
        },
        {
          "name": "submenu2",
          "project": [
            "p2"
          ]
        }
      ]
    }
  ]

我需要根据项目字段获取记录。如果项目字段是“全部”,我需要获取该子菜单下的所有项目。如果是特定项目,则只有我需要获取的那些项目。

这是我的收藏2

集合2

 "project": [
{
  "project_name": "p1",
  "sub_menus": "submenu1",

},
{
  "project_name": "p2",
  "sub_menus": "submenu2",

}
{
  "project_name": "p2",
  "sub_menus": "submenu1",

},
{
  "project_name": "p3",
  "sub_menus": "submenu2",

}
{
  "project_name": "p3",
  "sub_menus": "submenu1",

},
{
  "project_name": "p4",
  "sub_menus": "submenu2",

}

]

https://mongoplayground.net/p/qH9fuJorq6z。 我可以进行条件查找吗?

预期结果是

[
  {
    "_id": ObjectId("5ce7454f77af2d1143f84c38"),
    "menu_name": "mainmenu1",
    "sub_menus": [
      {
         "projectData": [
          {
            "project_name": "p1"      
          },
          {
          "project_name": "p2"
          },
          {
          "project_name": "p3"
          }
        ],
        "sub_menu_name": "submenu1"
      },
      {

        "projectData": [
          {
            "project_name": "p2"
          }
        ],
        "sub_menu_name": "submenu2"
      }
    ]
  }
]

【问题讨论】:

  • 你能展示你的预期结果吗?
  • 我添加了我的预期输出

标签: mongodb aggregation-framework lookup


【解决方案1】:

是的,您可以为$lookup pipeline 定义您自己的匹配条件,但由于您的结构嵌套很深,您需要在运行$lookup 之前使用$reducesub_menus 展平。一旦你把所有项目匹配到任何子菜单,你可以使用 $map 和 $filter 将它们放入 releval sub_menu:

db.collection1.aggregate([
    {
        $addFields: {
            sub_menus_flat: {
                $reduce: {
                    input: "$sub_menus",
                    initialValue: [],
                    in: {
                        $concatArrays: [ 
                            "$$value", 
                            { $map: { input: "$$this.project", as: "p", in: { name: "$$this.name", project: "$$p" } } } 
                        ]
                    }
                }
            }
        }
    },
    {
        $lookup: {
            from: "collection2",
            let: { sub_menus_flat: "$sub_menus_flat" },
            pipeline: [
                {
                    $match: {
                        $expr: {
                            $anyElementTrue: {
                                $map: {
                                    input: "$$sub_menus_flat",
                                    in: {
                                        $and: [
                                            { $eq: [ "$$this.name", "$sub_menus" ] },
                                            { $in: [ "$$this.project", [ "All", "$project_name" ] ] }
                                        ]
                                    }
                                }
                            }
                        }
                    }
                }
            ],
            as: "projects"
        }
    },
    {
        $project: {
            _id: 1,
            menu_name: 1,
            sub_menus: {
                $map: {
                    input: "$sub_menus",
                    in: {
                        sub_menu_name: "$$this.name",
                        projectData: {
                            $filter: {
                                input: "$projects",
                                as: "p",
                                cond: {
                                    $and: [
                                        { $eq: [ "$$p.sub_menus", "$$this.name" ] }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    {
        $project: {
            "sub_menus.projectData._id": 0,
            "sub_menus.projectData.sub_menus": 0
        }
    }
])

MongoDB Playground

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-16
    • 2020-01-24
    • 2016-01-23
    • 2019-01-16
    相关资源
    最近更新 更多