Schema help - "Hotel room" availability structure

1,414 views
Skip to first unread message

Alex Brown

unread,
Jun 10, 2012, 7:54:30 AM6/10/12
to mongod...@googlegroups.com
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.
 
For the “search results” I’d need to return hotel.name, hotel.description, hotel.star_rating.

I’m looking for the most efficient way to store this data for the type of query listed above?

Should the availability collection be it’s own collection, or a sub-document of Hotel?

If it’s own collection, should I add the lat lon to the availability (along with hotel_id) to make searching more efficient?

Daniel Coupal

unread,
Jun 10, 2012, 10:26:28 PM6/10/12
to mongodb-user
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.*

Alex Brown

unread,
Jun 11, 2012, 8:57:17 AM6/11/12
to mongod...@googlegroups.com
Cool..
Sounds like (hopefully) am on right track.

I agree with phase 1 - mostly
I do however need to show only those hotels that are available on a search results page.

So, I was thinking.

Query comes in something like:

location=<lat,lon>, radius=10, date_from=01,01,2013, date_to=08,01,2013

Query the hotels collection on location, to find a list of hotels nearby

Then, filter by the availability?

Would mapreduce be a good way to go for this?

Sam Millman

unread,
Jun 11, 2012, 9:01:49 AM6/11/12
to mongod...@googlegroups.com
To find a list of nearby hotels you will prolly want to use geospatial indexing with querying: http://www.mongodb.org/display/DOCS/Geospatial+Indexing

As for availability, it is upto your schema design really. You can put it all into one query as shown in that page in an example:

db.places.ensureIndex( { location : "2d" , category : 1 } );
db.places.find( { location : { $near : [50,50] }, category : 'coffee' } );


--
You received this message because you are subscribed to the Google
Groups "mongodb-user" group.
To post to this group, send email to mongod...@googlegroups.com
To unsubscribe from this group, send email to
mongodb-user...@googlegroups.com
See also the IRC channel -- freenode.net#mongodb

Alex Brown

unread,
Jun 11, 2012, 9:19:49 AM6/11/12
to mongod...@googlegroups.com
yeah, that's what i was talking about in last message-

1) Search for the hotels near the query (ignoring the availability at this stage)
2) Whittle down the results of above, and only return / show those with availability.

It's how to handle step 2 i'm unsure of at this stage...

Sam Millman

unread,
Jun 11, 2012, 9:26:10 AM6/11/12
to mongod...@googlegroups.com
I like quick, easy and dirty sometimes: I would aggregate an available field onto the hotel row every save of the hotel denoting whether or not a room is available, after which point you can just query for all available rooms.

The alternative is to house the roomid with its availability in the hotel collection in a subdocument while holding the rooms details in the hotel rooms collection to keep it relaitvely light weight.

Danny Clayden Chambers

unread,
Aug 1, 2015, 8:33:44 AM8/1/15
to mongodb-user
Hi Alex, I am building a meeting room booking app using the MEANjs stack and I wondered how you progressed with this? 

It would be really helpful to get an update or see an example of how your collections looked.

I realise it's been quite a long time but any info is most appreciated!

Danny

Alex Brown

unread,
Aug 12, 2015, 6:40:18 PM8/12/15
to mongod...@googlegroups.com
Hey, sorry for delay
This project was abandoned in the end, so we didn't actually get round to it

Sorry I can't be of any help

--
You received this message because you are subscribed to the Google Groups "mongodb-user"
group.
 
For other MongoDB technical support options, see: http://www.mongodb.org/about/support/.
---
You received this message because you are subscribed to a topic in the Google Groups "mongodb-user" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/mongodb-user/nlTTCOcT0Fw/unsubscribe.
To unsubscribe from this group and all its topics, send an email to mongodb-user...@googlegroups.com.
To post to this group, send email to mongod...@googlegroups.com.
Visit this group at http://groups.google.com/group/mongodb-user.
To view this discussion on the web visit https://groups.google.com/d/msgid/mongodb-user/8fe1f836-94fa-4f58-912a-304175c4426e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages