MongoDb:管道内查找错误:错误:参数必须是聚合管道运算符

问题描述

我有这三个模型:

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

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

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

  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",as: "current_student_profile",pipeline: [
      {
        $match: {
          videoURL: { $nin: [undefined,null] },]);

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

Error: Arguments must be aggregate pipeline operators

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

解决方法

您的查询有误。你不能像那样通过 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",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"),"profile" : ObjectId("604cb4b16b2dcb17e8b152b5")
},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"),"profile" : ObjectId("604cb4b16b2dcb17e8b152b7")
}

profiles 集合:

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

institutions 集合

/* 1 createdAt:3/13/2021,ObjectId("604cb4c36b2dcb17e8b152b9")
    ]
},"current_students" : [
        ObjectId("604cb4c36b2dcb17e8b152ba")
    ]
}
,

一定是这样的:

Institution.aggregate([
  {
    $lookup: {
      from: "users",},{
    $unwind: {
      path: "$current_student",{
    $lookup: {
      from: "profiles",}
   },{
     $match: {
       videoURL: { $nin: [undefined,}
]);

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