Documents
Description — Couchbase Lite Concepts - Data Model - Documents
Related Content — Databases | Blobs | Indexing
Overview
Document Structure
In Couchbase Lite the term 'document' refers to an entry in the database. You can compare it to a record, or a row in a table.
Each document has an ID or unique identifier. This ID is similar to a primary key in other databases.
You can specify the ID programmatically. If you omit it, it will be automatically generated as a UUID.
Couchbase documents are assigned to a Collection. The ID of a document must be unique within the Collection it is written to. You cannot change it after you have written the document.
The document also has a value which contains the actual application data. This value is stored as a dictionary of key-value (k-v) pairs. The values can be made of up several different Data Types such as numbers, strings, arrays, and nested objects.
Data Encoding
The document body is stored in an internal, efficient, binary form called Fleece. This internal form can be easily converted into a manageable native dictionary format for manipulation in applications.
Fleece data is stored in the smallest format that will hold the value whilst maintaining the integrity of the value.
Data Types
The Document class offers a set of property accessors for various scalar types, such as:
-
Boolean
-
Date
-
Double
-
Float
-
Int
-
Long
-
String
These accessors take care of converting to/from JSON encoding, and make sure you get the type you expect.
In addition to these basic data types Couchbase Lite provides for the following:
- Dictionary - Represents a read-only key-value pair collection
- MutableDictionary - Represents a writeable key-value pair collection.
- Array - Represents a writeable collection of objects.
- MutableArray - Represents a writeable collection of objects.
- Blob - Represents an arbitrary piece of binary data.
JSON
Couchbase Lite also provides for the direct handling of JSON data implemented in most cases by the provision of a ToJSON() method on appropriate API classes (for example, on MutableDocument, Dictionary, Blob and Array) — see Working with JSON Data.
Constructing a Document
An individual document often represents a single instance of an object in application code. A document might be considered equivalent to a row in a relational table; with each of the document's attributes being equivalent to a column.
Documents can contain nested structures. This allows developers to express many-to-many relationships without requiring a reference or junction table; and is naturally expressive of hierarchical data.
Most apps will work with one or more documents, persisting them to a local database and optionally syncing them, either centrally or to the cloud.
In this section we provide an example of how you might create a hotel document, which provides basic contact details and price data.
Data Model
hotel: {
type: string (value = `hotel`)
name: string
address: dictionary {
street: string
city: string
state: string
country: string
code: string
}
phones: array
rate: float
}
Open a Database
First open your database. If the database does not already exist, Couchbase Lite will create it for you.
const myDatabase = new Database('myDatabaseName', config);
See Databases for more information.
Create a Document
let document = new MutableDocument(hotel.id);
For more on using Documents, see Document Initializers and Mutability.
Create a Dictionary
Now create a mutable dictionary (address).
Each element of the dictionary value will be directly accessible via its own key.
// Create a new MutableDocument instance
const document = new MutableDocument();
// Now, populate the document as if it's a dictionary named 'address'
document.setString('address.street', '1 Main st.');
document.setString('address.city', 'San Francisco');
document.setString('address.state', 'CA');
document.setString('address.country', 'USA');
document.setString('address.code', '90210');
Create an Array
Since the hotel may have multiple contact numbers, provide a field (phones) as a mutable array.
// Create an instance of MutableDocument
const hotelInfo = new MutableDocument();
// Since `setArray` method accepts an array, directly pass the contact numbers as an array
hotelInfo.setArray("phones", ["650-000-0000", "650-000-0001"]);
Populate a Document
Now add your data to the mutable document created earlier. Each data item is stored as a key-value pair.
// Assuming address and phones are already defined as shown in previous examples
const address = {
street: "1 Main st.",
city: "San Francisco",
state: "CA",
country: "USA",
code: "90210"
};
const phones = ["650-000-0000", "650-000-0001"];
// Create an instance of MutableDocument
let hotelInfo = new MutableDocument();
// Add document type and hotel name as string
hotelInfo.setString("type", "hotel");
hotelInfo.setString("name", "Hotel Java Mo");
// Add average room rate (float)
hotelInfo.setFloat("room_rate", 121.75);
// Add address (dictionary)
hotelInfo.setDictionary("address", address);
// Add phone numbers (array)
hotelInfo.setArray("phones", phones);
Couchbase recommend using a type attribute to define each logical document type.
Save a Document
With the document now populated, we can persist to our Couchbase Lite database.
await collection.save(document);
Close the Database
With your document saved, you can now close our Couchbase Lite database.
database.close();
Working with Data
Date accessors
Couchbase Lite offers Date accessors as a convenience. Dates are a common data type, but JSON doesn’t natively support them, so the convention is to store them as strings in ISO-8601 format.
Example 1. Date Getter
This example sets the date on the createdAt property and reads it back using the Document.getDate() accessor method.
// Create an instance of MutableDocument
let document = new MutableDocument();
// Set the current date on the "createdAt" property
document.setDate("createdAt", new Date());
// Get the Date
const date = document.getDate("createdAt");
Using Dictionaries
Example 2. Read Only
// Get a document by ID
const doc: Document = collection.document('doc1');
// Getting a dictionary from the document's properties
const addressDict = doc.getDictionary('address');
// Access a value with a key from the dictionary
const street = addressDict?.getString('street');
// Iterate over the dictionary
Object.keys(addressDict || {}).forEach(key => {
console.log(`Key ${key} = ${addressDict[key]}`);
});
// Create a mutable copy
const mutableDict = { ...addressDict };
Example 3. Mutable
// Create a new "dictionary" as a simple JavaScript object
const addressDict = {
street: "1 Main st.",
city: "San Francisco",
};
// Create a new mutable document and add the dictionary to its properties
const mutableDoc = new MutableDocument("doc1");
mutableDoc.setDictionary("address", addressDict);
// Simulate saving the document
await collection.save(mutableDoc);
Using Arrays
Example 4. Read Only
// Getting a phones array from the document's properties
const phonesArray = document.data.phones;
// Get element count
const count = phonesArray.length;
// Access an array element by index
if (count >= 1) {
const phone = phonesArray[1];
console.log(`Second phone: ${phone}`);
}
// Iterate over the array
phonesArray.forEach((item, index) => {
console.log(`Item ${index} = ${item}`);
});
// Create a mutable copy of the array
const mutableArray = [...phonesArray];
Example 5. Mutable
// Create a new mutable document
const document = new MutableDocument();
// Prepare the data for the array
const phones = ["650-000-0000", "650-000-0001"];
// Assign the array to a key in the document
doc.setArray("phones", phones);
// Save the document with the new array to the database
await collection.save(doc);
Using Blobs
For more on working with blobs, see Blobs
Document Initializers
The MutableDocument
constructor can be used to create a new document where the document ID is randomly generated by the database.
Use the MutableDocument('specific_id')
initializer to create a new document with a specific ID.
The Collection.document
method can be used to get a document. If it doesn't exist in the collection, it will return null. This method can be used to check if a document with a given ID already exists in the collection.
Example 6. Persist a document
The following code example creates a document and persists it to the database.
// Create a new MutableDocument instance
const document = new MutableDocument();
// Set various fields on the document
document.setString('type', 'task');
document.setString('owner', 'todo');
document.setDate('createdAt', new Date());
// Persist the document to the database
await collection.save(document);
Document change events
It is possible to register for document changes. The following example registers for changes to the document with ID user.john and prints the verified_account property when a change is detected.
const token = collection.addDocumentChangeListener('user.john', async (change) => {
const document = await collection.document(change.documentID);
if (document !== null) {
console.log(`Status: ${document.getString('verified_account')}`);
}
});
// Remove the change listener when it is no longer needed
await collection.removeDocumentChangeListener(token);
Document Constraints
Couchbase Lite APIs do not explicitly disallow the use of attributes with the underscore prefix at the top level of document. This is to facilitate the creation of documents for use either in local only mode where documents are not synced.
_id
, _rev
and _sequence
are reserved keywords and must not be used as top-level attributes — see Example 13.
Example 13. Reserved Keys List
_attachments
_deleted
_id
_removed
_rev
_sequence