首页 > 解决方案 > 查询 $match 和 $project 重嵌套数据(MongoDB/聚合)

问题描述

我需要帮助编写仅$project“单个business.location.team.member”权限对象的 Mongoose 聚合查询。MongoDB 关于投影大量嵌套数据的文档不是很好,所以我有点卡住了。

示例集合:

const business = [
    {
      b_id: ObjectId("a"),
      locations: [ //can have multiple locations per business
        {
           l_id: ObjectId("b"),
           teams: [ //can have multiple teams per location
               {
                  t_id: ObjectId("c"),
                  members: [ //can have multiple members per team
                        {
                            m_id: ObjectId("d"),
                            permissions: { //each member has a single "permissions" object with different permission objects
                              p1: {
                                a: true,
                                b: false,
                                c: true,
                                d: false,
                              },
                              p2: {
                                a: true,
                                b: false,
                                c: true,
                                d: false,
                              }
                            }
                        }
                  ]
               } 
            ]
        }
      ]
    },
  ]

期望的回应:

const permissions = {
  p1: {
    a: true,
    b: false,
    c: true,
    d: false,
  },
  p2: {
    a: true,
    b: false,
    c: true,
    d: false,
  }
}

路线:

router.post("/", authUser, (req, res) => {
  const _ids = {
    b_id: req.body.b_id, //business _id === "a"
    l_id: req.body.l_id, //locations _id === "b"
    t_id: req.body.t_id, //teams _id === "c"
    m_id: req.body.m_id, //members _id === "d"
  }
  Business.aggregate([
    {
      $match: {
        b_id: ObjectId(_ids.b_id),
      },
    },
    {
      $project: {
      //how do I project the perms object from the correct member
      },
    },
  ]).then((perms) => {
    console.log(perms);
  });
});

任何帮助将不胜感激,谢谢!

标签: javascriptmongodbexpressmongooseaggregation-framework

解决方案


我想通了,它并不漂亮,但它完成了工作。必须有一些迭代的方法来做到这一点?

router.post("/", authUser, (req, res) => {
  const _ids = {
    b_id: req.body.b_id, //business _id === "a"
    l_id: req.body.l_id, //locations _id === "b"
    t_id: req.body.t_id, //teams _id === "c"
    m_id: req.body.m_id, //members _id === "d"
  }
  Business.aggregate([
    {
      $match: {
        b_id: ObjectId(_ids.b_id),
      },
    },
    {
      $unwind: "$locations",
    },
    {
      $match: {
        "locations.l_id": ObjectId(_ids.l_id),
      },
    },
    {
      $unwind: "$locations.teams",
    },
    {
      $match: {
        "locations.teams.t_id": ObjectId(_ids.t_id),
      },
    },
    {
      $unwind: "$locations.teams.members",
    },
    {
      $match: {
        "locations.teams.members.m_id": ObjectId(_ids.m_id),
      },
    },
    {
      $project: {
        permissions: ["$locations.teams.members.permissions"],
      },
    },
  ]).then((perms) => {
    res.status(200).json(perms[0].permissions[0]);
  });
});


推荐阅读