Reputation: 5970
I have a postgres database and I am using Sequelize. From tables vehicles and bookings I am trying to get all vehicles available given a startDate and endDate.
If I search Bookings with the give dates using:
Bookings.findAll({
where: {
[Op.or]: [
{ dateOut : { [Op.gt]: req.body.startDate} },
{ dateIn : { [Op.lt]: req.body.startDate} }
],
[Op.or]: [
{ dateOut : { [Op.gt]: req.body.endDate} },
{ dateIn : { [Op.lt]: req.body.endDate} }
]
}
})
I get all the vehicles that are booked during these dates. For exmple a search with startDate 2020-12-12 and endDate 2020-12-13 gives me these bookings:
[
{
"id": 13,
"startDate": "2020-12-05T00:00:00.000Z",
"endDate": "2020-12-13T00:00:00.000Z",
"vehicleId": 1
},
{
"id": 12,
"startDate": "2020-12-12T00:00:00.000Z",
"endDate": "2020-12-13T00:00:00.000Z",
"vehicleId": 2
}
]
Is it possible to use Sequelize to return the vehicles from the Vehicles table that are not found in this initial search?
UPDATE
Following Anatoly's answer I have this. It works in response to the results of the first query:
.then(bookingData => {
const bookedVehicleIds = bookingData.map(x => x.vehicleId)
Vehicles.findAll({
where: {
id: {
[Op.notIn]: bookedVehicleIds
}
}
})
.then(results => {
res.send(results);
})
})
Upvotes: 0
Views: 644
Reputation: 22758
I see no simple way to do one query instead of two ones (only using NOT EXISTS
subquery via sequelize.where
and sequelize.literal
).
So if you already have Booking
model instances you can just use Op.notIn
to get all Vehicles
that have not been booked on a given period:
const bookings = await Bookings.findAll({
// ... where condition omitted
})
const bookedVehicleIds = bookings.map(x => x.vehicleId)
const notBookedVehicles = await Vehicles.findAll({
where: {
id: {
[Op.notIn]: bookedVehicleIds
}
}
})
Upvotes: 1