MongoDb: Pipeline inside lookup error: Error: Arguments must be aggregate pipeline operators

MongoDb: Pipeline inside lookup error: Error: Arguments must be aggregate pipeline operators

我有这三个型号:

  1. Institution 型号:
const InstitutionSchema = new Schema({
  current_students: [
    {
      type: Schema.Types.ObjectId,
      ref: "users",
    },
  ],
});

module.exports = Institution = mongoose.model("institutions", InstitutionSchema);

它在 current_students 字段中包含对 User 模型的引用数组。

  1. User 型号:
const UserSchema = new Schema({
  profile: {
    type: Schema.Types.ObjectId,
    ref: "profiles",
  },
});

module.exports = User = mongoose.model("users", UserSchema);

profile 字段中引用了 Profile 模型。

  1. Profile 型号:
const ProfileSchema = new Schema({
  videoURL: {
    type: String,
  },
});

module.exports = Profile = mongoose.model("profiles", ProfileSchema);

我正在尝试获取 Profile.videoURL 不是 nullundefined 的机构的用户配置文件列表。这是我试过的:

Institution.aggregate([
  {
    $lookup: {
      from: "users",
      localField: "current_students",
      foreignField: "_id",
      as: "current_student",
    },
  },
  {
    $unwind: {
      path: "$current_student",
      preserveNullAndEmptyArrays: true,
    },
  },
  {
    $lookup: {
      from: "profiles",
      localField: "current_student.profile",
      foreignField: "_id",
      as: "current_student_profile",
    },
    pipeline: [
      {
        $match: {
          videoURL: { $nin: [undefined, null] },
        },
      },
    ],
  },
]);

但是,由于执行 $match 操作的最后一个管道,我一直收到此错误。

Error: Arguments must be aggregate pipeline operators

知道如何解决这个问题吗?

必须是这样的:

Institution.aggregate([
  {
    $lookup: {
      from: "users",
      localField: "current_students",
      foreignField: "_id",
      as: "current_student",
    },
  },
  {
    $unwind: {
      path: "$current_student",
      preserveNullAndEmptyArrays: true,
    },
  },
  {
    $lookup: {
      from: "profiles",
      localField: "current_student.profile",
      foreignField: "_id",
      as: "current_student_profile",
    }
   },
   {
     $match: {
       videoURL: { $nin: [undefined, null] },
     },
   }
]);

注意,这看起来像是关系 RDBMS 设计的“一对一”转换。通常这不是将每个 table 转换为 集合 的最佳方法,通常集合应该具有不同的设计。

您的查询有误。你不能那样传递 pipeline。看看 MongoDB 自己提供的 $lookup syntax. Also if you want to learn more about aggregations, I would suggest you to take up this Aggregation course。它对所有人免费。

试试这个查询:

db.institutions.aggregate([
    {
        $lookup: {
            from: "users",
            localField: "current_students",
            foreignField: "_id",
            as: "current_student",
        }
    },
    {
        $unwind: {
            path: "$current_student",
            preserveNullAndEmptyArrays: true,
        }
    },
    {
        $lookup: {
            from: "profiles",
            localField: "current_student.profile",
            foreignField: "_id",
            as: "current_student_profile",
        }
    },
    { $unwind: "$current_student_profile" },
    {
        $match: {
            "current_student_profile.videoURL": { $nin: [undefined, null] },
        }
    }
]);

输出:

/* 1 createdAt:3/13/2021, 6:18:26 PM*/
{
    "_id" : ObjectId("604cb49a6b2dcb17e8b152b2"),
    "name" : "Institute 1",
    "current_students" : [
        ObjectId("604cb4c36b2dcb17e8b152b8"),
        ObjectId("604cb4c36b2dcb17e8b152b9")
    ],
    "current_student" : {
        "_id" : ObjectId("604cb4c36b2dcb17e8b152b8"),
        "name" : "Dheemanth Bhat",
        "profile" : ObjectId("604cb4b16b2dcb17e8b152b5")
    },
    "current_student_profile" : {
        "_id" : ObjectId("604cb4b16b2dcb17e8b152b5"),
        "videoURL" : "http://abc1@xyz.com"
    }
},

/* 2 createdAt:3/13/2021, 6:18:26 PM*/
{
    "_id" : ObjectId("604cb49a6b2dcb17e8b152b3"),
    "name" : "Institute 2",
    "current_students" : [
        ObjectId("604cb4c36b2dcb17e8b152ba")
    ],
    "current_student" : {
        "_id" : ObjectId("604cb4c36b2dcb17e8b152ba"),
        "name" : "Alex Rider",
        "profile" : ObjectId("604cb4b16b2dcb17e8b152b7")
    },
    "current_student_profile" : {
        "_id" : ObjectId("604cb4b16b2dcb17e8b152b7"),
        "videoURL" : "http://abc3@xyz.com"
    }
}

测试数据:

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"),
    "videoURL" : "http://abc1@xyz.com"
},

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

/* 3 createdAt:3/13/2021, 6:18:49 PM*/
{
    "_id" : ObjectId("604cb4b16b2dcb17e8b152b7"),
    "videoURL" : "http://abc3@xyz.com"
}

institutions collection

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

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