提问者:小点点

使用mongoose节点js的级联连接


我尝试使用Node JS从MongoDB获取数据。我有三个模式:项目,用户和团队。我需要检索基于它的类型与工人用户的项目细节。我在为这些模式创建join时陷入困境:

项目:

const Project = new Schema({
    projectName: { type: String, required: true, trim: true },
    type: { type: String, required: true, trim: true },
    teamID: { type: Schema.Types.ObjectId, required: true },
});

团队

const Team = new Schema({
    teamId: { type: Schema.Types.ObjectId, required: true, trim: true },
    users: { type: [Schema.Types.ObjectId], required: true, trim: true },
    teamName: { type: String, required: true },
});

用户:

const User = new Schema({
    userId: { type: Schema.Types.ObjectId, required: true, trim: true },
    name: { type: String, required: true, trim: true },
    profilePicture: { type: String, required: true, trim: true },
});

我在想办法

[
   {
      projectName: "s",
      type: "w",
      users: ["Jon", "Ali", "Mark"]
   },
   {
      projectName: "a",
      type: "w",
      users: ["Jon", "Mark"]
   },   {
      projectName: "s",
      type: "w",
      users: ["Jon", "Ali", "Mark"]
   },
]

我尝试使用$lookup,但是我不能使用它,因为它的关系是复杂的多对多的关系。有没有比检索所有用户,所有团队和所有项目更高效的方式?


共1个答案

匿名用户

我认为除了聚合没有其他有效的方法,没有查找我们就不能连接集合,您可以使用嵌套查找,

  • $matchtype
  • 的条件
  • $lookup使用teamid
  • 加入团队集合
  • $matchTeamid
  • $lookup使用users数组
  • 加入用户集合
  • $project使用$map
  • 转换用户名数组
  • $addfields使用$arrayelemat
  • 在用户中获取用户数组
db.Project.aggregate([
  { $match: { type: "w" } },
  {
    $lookup: {
      from: "Team",
      let: { teamID: "$teamID" },
      as: "users",
      pipeline: [
        { $match: { $expr: { $eq: ["$$teamID", "$teamId"] } } },
        {
          $lookup: {
            from: "User",
            localField: "users",
            foreignField: "userId",
            as: "users"
          }
        },
        {
          $project: {
            users: {
              $map: {
                input: "$users",
                in: "$$this.name"
              }
            }
          }
        }
      ]
    }
  },
  { $addFields: { users: { $arrayElemAt: ["$users.users", 0] } } }
])

操场

第二种可能的方法是将$project$addfields阶段组合在一个阶段中,

  {
    $addFields: {
      users: {
        $arrayElemAt: [
          {
            $map: {
              input: "$users.users",
              in: "$$this.name"
            }
          },
          0
        ]
      }
    }
  }

操场