Mongoose避免使用空嵌套文档的结果

Mongoose避免使用空嵌套文档的结果,mongoose,filtering,populate,Mongoose,Filtering,Populate,我为此挣扎了几天。从理论上讲,这是一件容易的事情(至少在SQL中是这样) 我有3个系列,预订,套餐和个人资料 每个预订作为一个关联的包(嵌套文档/附加到预订),每个包作为一个配置文件,以相同的方式附加到包,好吗 我只想要一个查询,它返回所有预订,但包作为删除的配置文件时除外,这意味着配置文件文档在数据库中不再存在,它永远不应该发生,因为每个包都必须关联一个配置文件,但以防我想学习如何处理此类查询 以下是查询: filter = { $and: [ { 'package

我为此挣扎了几天。从理论上讲,这是一件容易的事情(至少在SQL中是这样)

我有3个系列,预订套餐个人资料

每个预订作为一个关联的包(嵌套文档/附加到预订),每个包作为一个配置文件,以相同的方式附加到包,好吗

我只想要一个查询,它返回所有预订,但包作为删除的配置文件时除外,这意味着配置文件文档在数据库中不再存在,它永远不应该发生,因为每个包都必须关联一个配置文件,但以防我想学习如何处理此类查询

以下是查询:

 filter = { $and: [ { 
            'package' : { $exists: true }, 
            'status':  {$ne: 'deleted'}
             
            }
        ]
    };

 return Booking.find( filter  )
                .populate(
                    [
                        {
                            path: 'package',
                            model: 'Package',
                            select : 'title description duration_minutes profile service',

                            populate : [
                                {
                                    path : 'profile',
                                    model: 'Profile',
                                    select : '_id name photo_profile',
                                    match: { '_id' : { $exists: true, $ne: null}},      
                                   // match: { 'name' : { $exists: true, $ne: null}},      

                                }
                                                 
                            ]
                
                    }
                  
                ]
                )
                .sort( { date: -1 } )
                .exec();
这些是模式: 预订

const bookingSchema = new Schema( {

    created_at: { 
        type: String,
        default: moment().format('llll')
    },

  
    package: {
        type: Schema.Types.ObjectId,
        ref: 'Package',
        required: [ true, 'A reference to a package must exist']
    },

 

    status: {
        type: String // ['pending', 'confirmed', 'finished']
    },
});
const profileSchema = new Schema( {

    created_at: { 
        type: Date, 
        default: Date.now 
    },

  
    name: {
        type: String
    },

    address: {
        type: String
        // required: [ true, 'An address to must exist']

    },

 
    geopoint: {
        type: { type: String },
        coordinates: []  // lat, lng
    },

   

    photo_profile: {
        type: String,
        default: 'user.jpg'
    },


    active: { 
        type: Boolean, 
        default: true
    },

  

    user: {
        type: Schema.Types.ObjectId,
        ref: 'User',
        required: [ true, 'A reference to a user must exist']
    },

});
套餐:

const packageSchema = new Schema( {

    created: { 
        type: Date, 
        default: Date.now 
    },


    title: {
        type: String,
        required: [ true, 'A title is mandatory']

    },


    profile: {
        type: Schema.Types.ObjectId,
        ref: 'Profile',
        required: [ true, 'A reference to a profile must exist']
    },

    service: {
        type: Schema.Types.ObjectId,
        ref: 'Service',
        required: [ true, 'A reference to a service must exist']
    },


    price_in: {
        type: Number
    },

  
});
配置文件

const bookingSchema = new Schema( {

    created_at: { 
        type: String,
        default: moment().format('llll')
    },

  
    package: {
        type: Schema.Types.ObjectId,
        ref: 'Package',
        required: [ true, 'A reference to a package must exist']
    },

 

    status: {
        type: String // ['pending', 'confirmed', 'finished']
    },
});
const profileSchema = new Schema( {

    created_at: { 
        type: Date, 
        default: Date.now 
    },

  
    name: {
        type: String
    },

    address: {
        type: String
        // required: [ true, 'An address to must exist']

    },

 
    geopoint: {
        type: { type: String },
        coordinates: []  // lat, lng
    },

   

    photo_profile: {
        type: String,
        default: 'user.jpg'
    },


    active: { 
        type: Boolean, 
        default: true
    },

  

    user: {
        type: Schema.Types.ObjectId,
        ref: 'User',
        required: [ true, 'A reference to a user must exist']
    },

});
我放什么都不重要
匹配:{'\u id':{$exists:true,$ne:null}} 因为查询也返回profiles NULL,这意味着profiles不存在,所以我真的不知道如何为嵌套文档执行“where”子句。 在当前场景中,当我尝试读取空配置文件时,会出现以下错误:

errTypeError:无法读取null的属性“\u id”
当然,bookings[key].package.profile不存在,但是,如何避免使用不存在的配置文件进行预订?这是主要问题

注意:我知道我可以通过.map函数或类似的代码过滤结果,但我真的很想学习并在查询中使用它

我只是想添加更多的信息,以防我的问题不清楚。 这是我在console.log进入控制台时得到的转储

这是一个响应示例,我得到了一些正确的结果(填充了现有配置文件),但有些配置文件为空(因为此配置文件不再存在)。我真的需要从查询结果中省略此预订,是否可以只在一个查询中执行此操作

 {
    requesters: 1,
    _id: sdfdsf43535353,
    date: 1595916000,
    buyer: { _id: dfsdf43535345353 },
    package: {
      duration_minutes: 60,
      _id: 5ee604103df1d70017ad12a7,
      service: null,
      title: ‘lorem ‘ipsum,
      description: ‘lorem ipsum;
      profile: null
    }


 {
  requesters: 1,
  _id: 5f6580eff34gfgfdg730251e,
  date: 1600527600,
  buyer: { _id: 5eeb26efdfdfdddfc0017c76e50 },
  package: {
    duration_minutes: 60,
    _id: 5f016c3192e71a00178ebc45,
    service: { _id: 5ee1bd48afgfg760a080, name: ‘lorem ipsum },
     title: ‘lorem ‘ipsum,
    profile: {
      photo_profile: 'ccddfdfdCCCCC.jpeg',
      _id: 5efeca84f0bcbd0017d708eb,
      name: '99 cool deal'
    },

},
非常感谢