A good rule when designing for MongoDB is to list as many queries as
you can, in order of importance.
Different sets of queries will likely give different models.
Based on my experience with Expedia and similar sites, I imagine your
site will go through those phases:
1) user enter search criteria
=> show a list of hotels matching user's criteria
2) user select an hotel
=> show availability per room type
3) user chooses to book a specific room type
=> go through the booking process
My design would have:
A) one collection for the hotels
- has all the information to describe the hotel, including its
coordinates
- includes a 'gross availability', which may not be exact
B) one collection for availability (which is the 'inventory'),
using your idea of one row per physical room per day
Phase 1)
Display all the hotels that match the query. You should be able to do
so by only querying the 'hotels' collection. The only thing you may
not include is the exact availability. You simply may not want to get
it right for this first query. Let me explain. If another user is in
the process of booking the last room of an hotel, do you want to show
the hotel as a possible match? I would go on the side of 'yes', just
in case the concurrent transaction does not complete. But you may
prefer loosing some immediate booking than annoy a customer with a
message that there is no more room later in his booking process.
So what you really need is a good enough inventory number to include
the hotel or not in the results. Only when a transaction is completed
that you could update the availability for the given hotel, or you
could even run a periodic task to do it. The point is that you don't
need the perfect availability at this point, especially because you
may still need the user to select the room type and specify attributes
like smoking/non-smoking.
Phase 2)
For a chosen hotel, report all the details with the exact availability
per room type. For this query, you only need to go to your
‘availability’ collection. Your idea to model it as one row per
individual room is great. It will let you track precisely which rooms
are currently getting booked and prevent double booking. Because every
row is a room, you have at this point a true count of each room type,
so the real availability for the given hotel. If you opted for a
periodic task to update your hotel collection, your application could
detect that no room is available and make a point to update the
'estimated availability' right away in the 'hotel' collection. One
more detail, since the booking has not started, you will need to
decide if you include a room undergoing a transaction of being book at
the exact moment by another user.
Phase 3)
Use the 'availability' collection to progress through your
transaction, recording the states. Once the booking is completed,
proceed with other tasks like updating the inventory, …
In conclusion, you did a good first pass on your schema.
Do list the queries that are important for you, in order to refine
your model.
Good luck,
Daniel Coupal
On Jun 10, 4:54 am, Alex Brown <
a...@alexjamesbrown.com> wrote:
> *I’m currently building an application with a similar model to hotel
> booking sites.
>
> Currently considering ways of handling availability searching.
>
> My model looks something a little bit like the below:
>
> Hotel
>
> - _id
> - name
> - description
> - star_rating
> - address
> - lat
> - lon
>
> I then thought of having an availability collection something like this:
>
> Availability
>
> - hotel_id (if availability is it's own collection)
> - date
> - room_type
> - room_max_occupancy
> - price
>
> date would store a single day the room was available
> room_type would be things like “Twin” “Double”
> room_max_occupancy would be 2, 3, etc...
>
> An example query would be: *
>
>
>
> > *a room in <location geocoded + radius> from 1st-8th June, for 2 people.*