【问题标题】:MongoDb: Pipeline inside lookup error: Error: Arguments must be aggregate pipeline operatorsMongoDb:管道内部查找错误:错误:参数必须是聚合管道运算符
【发布时间】:2021-06-12 11:48:37
【问题描述】:

我有这三个模型:

  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

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

【问题讨论】:

    标签: mongodb mongoose aggregation-framework lookup mongoose-populate


    【解决方案1】:

    您的查询是错误的。你不能像那样通过pipeline。看看$lookup 语法。另外,如果您想了解有关聚合的更多信息,我建议您使用 MongoDB 自己提供的 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收藏:

    /* 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收藏:

    /* 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收藏

    /* 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")
        ]
    }
    

    【讨论】:

      【解决方案2】:

      必须是这样的:

      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 设计的“一对一”转换。通常它不是将每个表格转换为集合的最佳方法,通常集合应该有不同的设计。

      【讨论】:

      • 这将返回一个空数组。我认为这是有道理的,因为 videoURL 是 Profile 模型中的字段,而不是机构模型中的字段。因此,正如您编写的那样,它检查的是 Institution.videoURL 而不是 Profile.videoURL,因此它始终是未定义的,并且返回的结果是一个空数组。
      猜你喜欢
      • 2014-12-11
      • 2016-09-17
      • 2019-03-27
      • 2017-08-24
      • 1970-01-01
      • 2018-04-24
      • 2020-09-10
      • 2018-04-22
      • 2021-06-16
      相关资源
      最近更新 更多