Mongoose 聚合:根据 Model.associated_Model.associated_Model.field returns 错误结果进行过滤

Mongoose aggregate: Filtering based on Model.associated_Model.associated_Model.field returns wrong result

我有三个模型 UserProfileInstitution

User

const UserSchema = new Schema({
  name: {
    type: Schema.Types.String,
  },
  profile: {
    type: Schema.Types.ObjectId,
    ref: "profiles",
  },
});

Profile

const ProfileSchema = new Schema({
  institution: {
    type: Schema.Types.ObjectId,
    ref: "institutions",
  },
});

Institution

const InstitutionSchema = new Schema({
  name: {
    type: String,
    required: true,
  },
});

我正在尝试获取用户列表 WHERE institution = institution_name:

User.aggregate([
    {
      $lookup: {
        from: "profiles",
        let: { profiles_id: "$profile" },
        pipeline: [
          {
            $lookup: {
              from: "institutions",
              pipeline: [
                {
                  $match: { name: institution_name },
                },
              ],
              as: "institution",
            },
          },
          { $unwind: "$institution" },
        ],
        as: "profile",
      },
    },
    { $unwind: "$profile" },
    {
      $project: {
        name: "$name",
        institution: "$profile.institution.name",
      },
    },
  ]);

出于某些奇怪的原因,这是 return 所有用户的列表,但它用我使用的过滤值 institution_name 替换了机构字段。 知道如何解决这个问题吗?

查询中的主要错误是您没有根据某些条件执行联接。在第一个 $lookupprofiles collection 中,您将 profile 作为 profiles_id 传递,但没有在管道中使用它。第二个 $lookupinstitutions 的情况也是如此。

试试这个:

const institution_name = "Institute 1";

db.users.aggregate([
    {
        $lookup: {
            from: "profiles",
            let: { profiles_id: "$profile" },
            pipeline: [
                {
                    $match: {
                        // Join condition.
                        $expr: { $eq: ["$_id", "$$profiles_id"] }
                    }
                },
                {
                    $lookup: {
                        from: "institutions",
                        let: { institution_id: "$institution" },
                        pipeline: [
                            {
                                $match: {
                                    name: institution_name,
                                    // Join condition.
                                    $expr: { $eq: ["$_id", "$$institution_id"] }
                                }
                            }
                        ],
                        as: "institution"
                    }
                },
                { $unwind: "$institution" },
            ],
            as: "profile",
        }
    },
    { $unwind: "$profile" },
    {
        $project: {
            name: "$name",
            institution: "$profile.institution.name"
        }
    }
]);

输出:

/* 1 createdAt:3/13/2021, 6:19:07 PM*/
{
    "_id" : ObjectId("604cb4c36b2dcb17e8b152b8"),
    "name" : "Dheemanth Bhat",
    "institution" : "Institute 1"
},

/* 2 createdAt:3/13/2021, 6:19:07 PM*/
{
    "_id" : ObjectId("604cb4c36b2dcb17e8b152b9"),
    "name" : "Ahmed Ghrib",
    "institution" : "Institute 1"
}

测试数据:

users collection:

/* 1 createdAt:3/13/2021, 6:19:07 PM*/
{
    "_id" : ObjectId("604cb4c36b2dcb17e8b152b8"),
    "name" : "Dheemanth Bhat",
    "profile" : ObjectId("604cb4b16b2dcb17e8b152b5")
},

/* 2 createdAt:3/13/2021, 6:19:07 PM*/
{
    "_id" : ObjectId("604cb4c36b2dcb17e8b152b9"),
    "name" : "Ahmed Ghrib",
    "profile" : ObjectId("604cb4b16b2dcb17e8b152b6")
},

/* 3 createdAt:3/13/2021, 6:19:07 PM*/
{
    "_id" : ObjectId("604cb4c36b2dcb17e8b152ba"),
    "name" : "Alex Rider",
    "profile" : ObjectId("604cb4b16b2dcb17e8b152b7")
}

profiles collection:

/* 1 createdAt:3/13/2021, 6:18:49 PM*/
{
    "_id" : ObjectId("604cb4b16b2dcb17e8b152b5"),
    "institution" : ObjectId("604cb49a6b2dcb17e8b152b2")
},

/* 2 createdAt:3/13/2021, 6:18:49 PM*/
{
    "_id" : ObjectId("604cb4b16b2dcb17e8b152b6"),
    "institution" : ObjectId("604cb49a6b2dcb17e8b152b2")
},

/* 3 createdAt:3/13/2021, 6:18:49 PM*/
{
    "_id" : ObjectId("604cb4b16b2dcb17e8b152b7"),
    "institution" : ObjectId("604cb49a6b2dcb17e8b152b3")
},

/* 4 createdAt:3/13/2021, 6:18:49 PM*/
{
    "_id" : ObjectId("604cb4b16b2dcb17e8b152b8"),
    "institution" : ObjectId("604cb49a6b2dcb17e8b152b4")
}

institutions collection:

/* 1 createdAt:3/13/2021, 6:18:26 PM*/
{
    "_id" : ObjectId("604cb49a6b2dcb17e8b152b2"),
    "name" : "Institute 1"
},

/* 2 createdAt:3/13/2021, 6:18:26 PM*/
{
    "_id" : ObjectId("604cb49a6b2dcb17e8b152b3"),
    "name" : "Institute 2"
},

/* 3 createdAt:3/13/2021, 6:18:26 PM*/
{
    "_id" : ObjectId("604cb49a6b2dcb17e8b152b4"),
    "name" : "Institute 3"
}