Designing a relationship between documents?


#1

Learning how to build a relationship between documents in Couchbase. Maybe this question asked better with example.

Let say there are hotels and guests. Many hotels and many guests.

{
  "_id": "hotel1"
  "type": "hotel"
  "name": "Hilton"
  ...
}

{
  "_id": "hotel2"
  "type": "hotel"
  "name": "Hampton"
  ...
}


{
  "_id" : "guest1"
  "type": "guest"
  "name": "John"
  ...
}
{
  "_id" : "guest2"
  "type": "guest"
  "name": "Erin"
  ...
}

One way to build a relationship is to embed guest IDs within hotel documents but this is going to get very big over time.

The other way is that to embed hotel IDs within guest documents and create views for each hotel to list its guests. Since hotels are added over time, these views need to dynamically added whenever hotel document is created. If there are 500 hotels, they will be 500 views.

What is the cleaner way to build relationship for such data in order to get efficient access to list of guests in relation to a hotel?


#2

Hi @twl,

from your documents, I assume you are coming from MongoDB (_id)? Data modeling with couchbase is a little different if you want to get the best out of it.

First, check out our webinars and blog posts on document modeling, there is lots of viable information in there you can use to properly build applications.

Now to your specific question:

  • You don’t need to create a view for each hotel, you can create one view for all hotels and then at query time filter by the hotel. This is a very common and efficient approach.

You can add a list of visited hotels to each guest and then write a view with something like:

function (doc, meta) {
    if (doc.type == "guest") {
        for (i = 0; i < doc.visited.length; i++) {
            emit([doc.visited[i], doc._id], null);
        }
    }
} 

This will give you an index sorted by the hotel id and then you get each guest visited per hotel.
This can be even more advanced if you emit timestamps to the hotels with dateToArray() so you can first filter on the hotel and then on the date so you can get records for specific date ranges per hotel.