简体   繁体   中英

How to return all subdocuments with Mongoose

I'm working with mongoose and want to reach all the subdocuments within a subdocument. In short, I want to return all booking subdocuments that are stored in the dentist subdocuments that are stored in the clinic documents.

Right now my solution contain a lot of loops, but there have to be a better way. The code below works and describes what my ambition is. I'm willing to re-arrange the schema structure if needed. Please help me to improve on it.

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));
})

The Clinic Schema:

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},
});

The Dentist Schema:

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],
});

The 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 },
});

I guess the structure of the collection Clinic looks like this

[
    {
        _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'}}]}
        ]
    }
]

if the structure is correct, then you can run the aggregation

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'
                }
            }
        }
    ]
)

and you can get the result like

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM