Search code examples
node.jsexpressmongoosemongoose-schemamongoose-populate

How to populate the nested objects in mongoose?


here's the booking schema

const bookingSchema = new mongoose.Schema({
  userId: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "User",
    required: true,
  },
  routeId:{
    type: mongoose.Schema.Types.ObjectId,
    ref: "Route",
    required: true,
  }
})

In this table the routeId(route schema) contains the Bus table(referenced).

const routeSchema = new mongoose.Schema({
  location:{
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Location',
    required: true
  },
  duration: {
    type: Number,
    required: true
  },
  Bus:{
    type: mongoose.Schema.Types.ObjectId,
    ref:"Bus",
    required: true
  },
  date: {
    type:String,
    required: true
  },
},
{
  timestamps: true,
});

and then finally the bus model

const busSchema = new mongoose.Schema(
  {
    busNumber: {
      type: String,
      unique: true,
      required: true,
    },
    seats: {
      type: Number,
    },
  },
  {
    timestamps: true,
  }
);

Now I want to show only bus number and not whole bus data. this is the response I am getting. https://i.sstatic.net/S1qyZ.png

this is the query that I applied.

router.get("/bus/myBooking/one/:id", auth, async (req, res) => {
  const _id = req.params.id;
  const myBooking = await Booking.findById({ _id })
    .populate({path: 'routeId', populate: 'Bus'})
    .select(["-_id","-userId","-createdAt","-updatedAt","-__v","-passengers._id","-departureDetails._id","-arrivalDetails._id"]);
  try {
    return !myBooking
      ? res.status(404).send("No booking found")
      : res.status(200).send(myBooking);
  } catch (e) {
    res.status(500).send();
  }
});

Solution

  • This method works on some versions of mongoose, So you can try this:

     await Booking.findById({ _id })
      .populate({ 
       path: 'routeId',
          populate: {
             path: 'Bus',
             model: Bus,
             select:"-_id busNumber"
       } 
     })