如何使用 Mongoose 返回所有子文档

Posted

技术标签:

【中文标题】如何使用 Mongoose 返回所有子文档【英文标题】:How to return all subdocuments with Mongoose 【发布时间】:2021-02-17 18:15:28 【问题描述】:

我正在使用 mongoose 并希望访问子文档中的所有子文档。简而言之,我想返回存储在 clinic 文档中的 dentist 子文档中的所有 booking 子文档。

现在我的解决方案包含很多循环,但必须有更好的方法。下面的代码有效并描述了我的野心。如果需要,我愿意重新安排架构结构。请帮助我改进它。

router.post('/available-times', function (req, res) 
  let available_times = [];
  Clinic.find()
  .then((clinics)=> 
    clinics.forEach((clinic) =>  
      clinic.dentists.forEach((dentist) => 
        dentist.schedule.forEach((booking) => 
          if(!booking.reserved)
            available_times.push(booking)
          
        )
      )
    );
    const response = 
          success: true,
          result: available_times,
          
        res.json(response)
      )
      .catch(err => res.status(400).json("Error: " + err));
)

诊所架构:

const clinicSchema = new Schema(
    address:                             type: String,
    clinic_name:                         type: String,
    contact_person:                      type: String,
    dentists:                           [Dentist.schema],
    description:                         type: String,
    email:                               type: String,
    isVerified:                          type: Boolean, default: false ,
    location:                            type: String,
    logo_url:                            type: String,
);

牙医架构:

const dentistSchema = new Schema(
    biography:               type: String,
    languages_spoken:       [String],
    name:                    type: String,
    offered_services:       [String],
    picture_url:             type: String,
    reviews:                 type: Array,
    schedule:               [Booking.schema],
);

预订架构:

const bookingSchema = new Schema(
    title:               type: String,
    start:               type: Date,
    end:                 type: Date,
    customer_email:      type: String,
    customer_name:       type: String,
    customer_phone:      type: String,
    dentist_id:          type: String,
    dentist_name:        type: String,
    clinic_id:           type: String,
    price:               type: Number,
    reserved:            type: Boolean, default: false ,
);

【问题讨论】:

虽然所有信息都在帖子中。示例文档或指向它的链接会有所帮助 我现在添加了示例文档 【参考方案1】:

我猜Clinic集合的结构是这样的

[
    
        _id: ObjectId('5fa36e4d0e5796a0221bad0d'),
        dentists: [
            schedule: [booking: reserved: true, foo: 'bar1'],
            
                schedule: [
                    booking: reserved: false, foo: 'bar2',
                    booking: reserved: true, foo: 'bar3'
                ]
            
        ]
    ,
    
        _id: ObjectId('5fa373340e5796a0221bad0e'),
        dentists: [
            schedule: [booking: reserved: true, foo: 'bar4'],
            schedule: [booking: reserved: false, foo: 'bar5']
        ]
    
]

如果结构正确,则可以运行聚合

Clinic.aggregate(
    [
        
            $project: 
                _id: 0,
                temp: '$dentists.schedule.booking'
            
        ,
        
            $unwind: 
                path: '$temp'
            
        ,
        
            $unwind: 
                path: '$temp'
            
        ,
        
            $match: 
                'temp.reserved': true
            
        ,
        
            $group: 
                _id: null,
                available_times: 
                    $addToSet: '$temp'
                
            
        
    ]
)

你可以得到类似的结果


    _id: null,
    available_times: [
        reserved: true, foo: "bar4",
        reserved: true, foo: "bar3",
        reserved: true, foo: "bar1"
    ]


【讨论】:

谢谢,我试试看。您对 Clinic 集合的结构是正确的。 老实说,虽然该操作能够获取您想要的数据,但为 clinicdentistbooking 实现三个单独的集合,并参考这些集合之间的文档更好的做法。 谢谢,这正是我一直在寻找的指导。数据库超出了我的能力,是时候将它分解成更小的部分了。

以上是关于如何使用 Mongoose 返回所有子文档的主要内容,如果未能解决你的问题,请参考以下文章

单独文件上的 Mongoose 子文档,如何嵌入它们

Mongoose:如何将子文档中的数组提取到父文档中的单个数组中

如何使用另一个集合 mongoose 查找子查询文档

MongoDB:如何使用 Mongoose 添加或更新子文档?

如何在 mongoose/mongodb 查询子文档中使用 mapreduce?

如何在 mongoose/mongodb 查询子文档中使用 mapreduce?