Documents — Data Model


    Description — Couchbase Lite concepts — Data model — Documents
    Related Content — Databases | Blobs | Indexing |


    In Couchbase Lite, a document’s body takes the form of a JSON object — a collection of key/value pairs where the values can be different types of data such as numbers, strings, arrays or even nested objects. Every document is identified by a document ID, which can be automatically generated (as a UUID) or specified programmatically; the only constraints are that it must be unique within the database, and it can’t be changed.


    The following methods/initializers can be used:

    • The MutableDocument() initializer can be used to create a new document where the document ID is randomly generated by the database.

    • The MutableDocument(String id) initializer can be used to create a new document with a specific ID.

    • The Database.document(withID:) method can be used to get a document. If it doesn’t exist in the database, it will return null. This method can be used to check if a document with a given ID already exists in the database.

    The following code example creates a document and persists it to the database.

    Example 1. Persist a document
    let newTask = MutableDocument()
        .setString("task", forKey: "type")
        .setString("todo", forKey: "owner")
        .setDate(Date(), forKey: "createdAt")
    try database.saveDocument(newTask)


    By default, when a document is read from the database it is immutable. The Document.toMutable() method should be used to create an instance of the document which can be updated.

    Example 2. Make a mutable document

    Changes to the document are persisted to the database when the save method is called.

    guard let document = database.document(withID: "xyz") else { return }
    let mutableDocument = document.toMutable()
    mutableDocument.setString("apples", forKey: "name")
    try database.saveDocument(mutableDocument)

    Typed Accessors

    Scalar type

    The Document class now offers a set of property accessors for various scalar types, including boolean, integers, floating-point and strings. These accessors take care of converting to/from JSON encoding, and make sure you get the type you’re expecting.

    Date accessors

    In addition, as a convenience we offer Date accessors. 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. The following example sets the date on the createdAt property and reads it back using the accessor method.

    newTask.setValue(Date(), forKey: "createdAt")
    let date = "createdAt")

    Checking for properties

    To check whether a given property exists in the document, you should use the Document.Contains(key:) method.

    If the property doesn’t exist in the document it will return the default value for that getter method (0 for 0.0 for Document.float() etc.).

    Document to dictionary

    A Document can be converted to a plain dictionary type. That’s often useful to pass the document contents as a plain object to another method.

    Example 3. Convert to dictionary type
    newTask.toDictionary() // returns a Dictionary<String, Any>

    Batch operations

    If you’re making multiple changes to a database at once, it’s faster to group them together. The following example persists a few documents in batch.

    do {
        try database.inBatch {
            for i in 0...10 {
                let doc = MutableDocument()
                doc.setValue("user", forKey: "type")
                doc.setValue("user \(i)", forKey: "name")
                doc.setBoolean(false, forKey: "admin")
                try database.saveDocument(doc)
                print("saved user document \(doc.string(forKey: "name")!)")
    } catch let error {

    At the local level this operation is still transactional: no other Database instances, including ones managed by the replicator can make changes during the execution of the block, and other instances will not see partial changes. But Couchbase Mobile is a distributed system, and due to the way replication works, there’s no guarantee that Sync Gateway or other devices will receive your changes all at once.

    Document change events

    It’s also 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.

    database.addDocumentChangeListener(withID: "user.john") { (change) in
        if let document = self.database.document(withID: change.documentID) {
            print("Status :: \(document.string(forKey: "verified_account")!)")

    Document Expiration

    Document expiration allows users to set the expiration date to a document. When the document is expired, the document will be purged from the database. The purge will not be replicated to Sync Gateway.

    The following example sets the TTL for a document to 5 minutes from the current time.

    // Purge the document one day from now
    let ttl = .day, value: 1, to: Date())
    try database.setDocumentExpiration(withID: "doc123", expiration: ttl)
    // Reset expiration
    try db.setDocumentExpiration(withID: "doc1", expiration: nil)
    // Query documents that will be expired in less than five minutes
    let fiveMinutesFromNow = Date(timeIntervalSinceNow: 60 * 5).timeIntervalSince1970
    let query = QueryBuilder

    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, or when used exclusively in peer-to-peer sync.

    "_id", :"_rev" and "_sequence" are reserved keywords and must not be used as top-level attributes — see Example 4.

    Users are cautioned that any attempt to sync such documents to Sync Gateway will result in an error. To be future proof, you are advised to avoid creating such documents. Use of these attributes for user-level data may result in undefined system behavior.

    For more guidance — see: Sync Gateway - data modeling guidelines

    Example 4. Reserved Keys List
    • _attachments

    • _id

    • _deleted

    • _removed

    • _rev