How to get only matched data in node.js using mongoose?
Published: 2022-05-29 06:53:10

I am building a bus ticket booking app in node.js. I want to fetch only related data about queries not all the data But I am getting all the data about Bus.

Here is the location model. only admin can enter data about locations.

```
const locationSchema = new mongoose.Schema(
  {
    departureLocation: {
      name: {
        type: String,
        required: true,
        lowercase: true
      },
      time: {
        type: String,
        required: true,
      },
      subLocations: { type: [String], lowercase: true },
    },
    arrivalLocation: {
      name: {
        type: String,
        required: true,
        lowercase: true
      },
      time: {
        type: String,
        required: true,
      },
      subLocations: { type: [String], lowercase: true },
    },
  },
  {
    timestamps: true,
  }
);
```
Here is the route table. Again admin...

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

```
const busSchema = new mongoose.Schema({
    busNumber: {
      type: String,
      unique: true,
      required: true,
    },
    seats: {
      type: Number,
    },
    route: {
      type: mongoose.Schema.Types.ObjectId,
      ref: "Route",
      required: true,
    },
  },
  {
    timestamps: true,
  });
```
and here finally the booking table:

```
const bookingSchema = new mongoose.Schema({
  userId: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "User",
    required: true,
  },
  busId: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "Bus",
    required: true,
  },
  passengers: [
    {
      name: { type: String, required: true, trim: true },
      gender: { type: String, required: true, trim: true },
      age: { type: Number, required: true, trim: true },
    }],
  phone: {
    type: Number,
    required: true,
  },
  email: {
    type: String,
    required: true,
  },
  bookingDate: {
    type: String,
    required: true,
  },
  fare: {
    type: Number,
    required: true,
  },
  seats: {
    required: true,
    type: [Number],
  },
  departureDetails: [
    {
      city: { type: String, required: true, trim: true },
      location: { type: String, required: true, trim: true },
      time: { type: String, required: true, trim: true },
      date: { type: String, required: true, trim: true },
    },
  ],
  arrivalDetails: [
    {
      city: { type: String, required: true, trim: true },
      location: { type: String, required: true, trim: true },
      time: { type: String, required: true, trim: true },
      date: { type: String, required: true, trim: true },
    },
  ],
},{
    timestamps:true
});
```
Whenever an authorized user enters the booking data It is getting saved to the database. No problem whatsoever

Now I want to show every user(Non-authorized as well) of my app about trips(routes), the bus which will run on that particular trip and reserved and available seats in that particular bus which is currently stored.

But the problem is that I am getting all the buses even if it is not on that trip.

here is the query:

```
router.get("/trip/single", async (req, res) => {
  if (!req.query.departure || !req.query.arrival || !req.query.date) {
    return res.send({
      error: "Please enter the data to get the trip",
    });
  }
  const { departure, arrival, date } = req.query;
 
  let locations = await Location.find({
    'departureLocation.name': departure,
    'arrivalLocation.name': arrival,
  });
 
  const ids = locations.map(location => location._id)
 
  const routes = await Route.find({$and: [{location : {$in: ids}},{date}]});
  const route = routes.find(()=>{
    return ([{ date }, { routes }])
  });
 
  let buses = await Bus.find({})
  let matchedBuses = buses.filter((bus)=> {
    return bus.routes === locations._id
  })
  
  const bookings = await Booking.find({})
  const busIdWithSeatsObj = {}
  for(let i = 0; i < matchedBuses.length; i++){
    let currentBusSeats = []
    const busBookings = bookings.filter((booking) => {
      return (booking.departureDetails.date === date &&
        booking.busId.toString() === matchedBuses[i]._id.toString()
        )
    })
    busBookings.forEach((booking) => {
      currentBusSeats = [...currentBusSeats, ...booking.seats]
    })
    busIdWithSeatsObj[matchedBuses[i].seats] = currentBusSeats
  }
 
  res.status(200).send({route, matchedBuses, busIdWithSeatsObj});
});
```
Now I also want to fetch details by Id(only single bus).

How to do that?

Can anyone help me out here?

here's the input data image with result for date: 2022-06-02 which is actually available in the database : https://i.stack.imgur.com/FlfaG.png

This is the second query with result for date: 2022-06-01. It is not available in the database still showing matchedBus.: https://i.stack.imgur.com/xY5pW.png Now route data is gone but matched buses still shows.