A newer version of this documentation is available.

View Latest

Travel App Data Model

    The data model for the travel app uses several distinct document types: airline, route, airport and landmark.

    Our tutorial introduction to using the SDK uses the Travel Sample data bucket.

    The Travel App data model

    The data model for the travel app uses several distinct document types: airline, route, airport, and hotel.

    The model for each kind of document contains:

    • A key that acts as a primary key

    • An id field that identifies the document

    • A type field that identifies the kind of document

    The following figure illustrates the relationship between the different kinds of documents in version 5.1 of the Travel App. It shows the primary key, ID, and type fields that each document has, plus a few representative fields in each type of document.

    Travel Sample data model diagram
    Figure 1. Documents in the Travel App 5.1 data model

    Landmark documents are not used in the travel-sample application, which focuses on a more specific subset of point of interests that have their own type: hotels.

    Hotels, like landmarks, don’t have relations to other types.

    Airline documents

    Airline documents contain details about airlines such as the name of the airline, International Air Transport Association (IATA) two-character airline designator, International Civil Aviation Organization (ICAO) three-character airline designator, and the airline call sign.

    For airline documents, the value of the type field is airline.

    Airline document model
    airline_24 			   ←This is the key, which also acts as a primary key
      "active": "Y",
      "callsign": "AMERICAN",
      "country": "United States",
      "iata": "AA",
      "icao": "AAL",
      "id": "24",
      "name": "American Airlines",
      "type": "airline"              ←This is the type identifier for the document

    Route documents

    Route documents contain details about flights such as the name of the airline, departure airport, destination airport, number of stops during the flight, type of aircraft, flight number, and flight schedule.

    Route documents also contain a foreign key identifier, airlineid, that is used to retrieve the document that contains information about the airline that flies the route. The value of the airlineid field is identical to the key for the corresponding airline document.

    For route documents, the value of the type field is route.

    Route document model
    route_5966                         ←This is the key, which also acts as a primary key
      "id": "5966",
      "type": "route",               ←This is the type identifier for the document
      "airline": "AA",
      "airlineid": "airline_24",     ←This is the foreign key identifier to an airline document
      "sourceairport": "MCO",
      "destinationairport": "SEA",
      "stops": "0",
      "equipment": "737",
      "schedule": [
          {"day": 1, "utc": "13:25:00", "flight": "AA788"},
          {"day": 4, "utc": "13:25:00", "flight": "AA419"},
          {"day": 5, "utc": "13:25:00", "flight": "AA519"}

    Airport documents

    Airport documents contain details about airports such as name, location, time zone, ICAO four-character alphanumeric airport code, and Federal Aviation Administration (FAA) location identifier.

    For airport documents, the value of the type field is airport.

    Airport document model
    airport_3577                       ←This is the key, which also acts as a primary key
      "travel-sample": {
          "airportname": "Seattle Tacoma Intl",
          "city": "Seattle",
          "country": "United States",
          "faa": "SEA",
          "geo": {
              "alt": 433,
              "lat": 47.449,
              "lon": -122.309306
          "icao": "KSEA",
          "id": 3577,
          "type": "airport",         ←This is the type identifier for the document
          "tz": "America/Los_Angeles"

    Hotel documents

    Hotel documents are all about a specific type of point of interests: hotels. They include information such as a name, description, location (coutry, state, city and address), price and services, and even customer reviews.

    For hotel documents, the value of the type field is hotel.

    Hotel document model
    hotel_10180                     ←This is the key, which also acts as a primary key
        "address": "8301 Hollister Ave",
        "checkin": "12PM",
        "checkout": "4PM",
        "city": "Santa Barbara",
        "country": "United States",
        "description": "Located on 78 acres of oceanfront property, this resort is an upscale experience that caters to luxury travelers. There are 354 guest rooms in 19 separate villas, each in a Spanish style. Property amenities include saline infinity pools, a private beach, clay tennis courts, a 42,000 foot spa and fitness center, and nature trails through the adjoining wetland and forest. The onsite Miro restaurant provides great views of the coast with excellent food and service. With all that said, you pay for the experience, and this resort is not for the budget traveler.  In addition to quoted rates there is a $25 per day resort fee that includes a bottle of wine in your room, two bottles of water, access to fitness center and spa, and internet access.",
        "free_breakfast": true,
        "free_internet": false,
        "free_parking": false,
        "geo": {
            "accuracy": "ROOFTOP",
            "lat": 34.43429,
            "lon": -119.92137
        "id": 10180,
        "name": "Bacara Resort \u0026 Spa",
        "pets_ok": false,
        "price": "$300-$1000+",
        "reviews": [
                "author": "Orval Lebsack",
                "content": "I stayed there with a friend for a girls trip around St. Patricks Day. This was my third time to NOLA, my first at Chateau Lemoyne. The location is excellent....very easy walking distance to everything, without the chaos of staying right on Bourbon Street. Even though its a Holiday Inn, it still has the historical feel and look of NOLA. The pool looked nice too, even though we never used it. The staff was friendly and helpful. Chateau Lemoyne would be hard to top, considering the price.",
                "date": "2013-10-26 15:01:39 +0300",
                "ratings": {
                    "Cleanliness": 5,
                    "Location": 5,
                    "Overall": 4,
                    "Rooms": 4,
                    "Service": 4,
                    "Sleep Quality": 5,
                    "Value": 4
        "state": "California",
        "type": "hotel",         ←This is the type identifier for the document
        "url": "http://www.bacararesort.com/",
        "vacancy": true

    N1QL query anatomy

    The Couchbase Query API is a powerful tool for efficient retrieval of information from a document data store. In each SDK-specific travel application, queries about flights are created by a dedicated module (for example in Node.js, the flightPath.js module). Here’s an example of a query that finds flights between Seattle-Tacoma International Airport (SEA) and Orlando International Airport (MCO), followed by a description of what’s happening in the query:

    SELECT a.name, s.flight, s.utc, r.sourceairport, r.destinationairport, r.equipment
    FROM `travel-sample` r
    UNNEST r.schedule s
    JOIN `travel-sample` a ON KEYS r.airlineid
    WHERE r.sourceairport='SEA' AND r.destinationairport='MCO' AND s.day=6
    ORDER BY a.name

    N1QL provides JOIN functionality, something previously not possible in a document database. For two documents to be joined in the result of a SELECT statement, one of them must contain a field whose value is equal to the Couchbase key of the other document. The following example shows two documents that demonstrate that requirement and a SELECT statement that joins them:

    "keyA" is the Couchbase KV key for Doc A.
    Doc A: { some fields }
    Doc B: { some fields "joinField": "keyA" }
    SELECT * FROM default b JOIN default a ON KEYS b.joinField

    The data model for the travel application includes an airlineid field in each route document. That airlineid field is used as a foreign key identifier and corresponds to the key for an airline document. To select the airline name a.name, the query uses the following clause: JOIN `travel-sample` a ON KEYS r.airlineid.

    One of the powerful features available in the N1QL query language is the ability to UNNEST or flatten, the results returned in the SELECT statement. This is frequently needed when working with JSON documents, which may have rich heirarchies. In the data model for the travel application, each route document contains a nested collection of schedule documents. To alleviate a complicated JSON parsing code pattern for the return results, you can have the query execution UNNEST the schedule documents, so they become the root-level fields in the returned results.

    Standard SQL syntax is used in the WHERE clause for the SELECT statement. The result set is ordered by the a.name field, which contains the airline name.

    Refer to the Querying with N1QL section for more information on using N1QL with the SDKs.


    In preparation for the introduction of Collections in an upcoming release of the Couchbase Data Platform, a version of the Travel Sample application is provided which contains a script to split out user data into a separate collection. To try this out with Couchbase Server 6.5 and 6.6, you will need to enable the Collections Developer Preview. This Developer Preview is not to be used in production.

    The Beta release of Couchbase Server 7.0 offers the chance to try out a Collections-ready Travel Sample Bucket.

    Collections-aware Travel Sample data model diagram

    Further Reading

    The Travel Sample data set is embedded in many of our examples.