Manage Scopes and Collections

      +
      Scopes and collections allow you to organize your documents within a database.
      At a glance

      Use collections to organize your content in a database

      For example, if your database contains travel information, airport documents can be assigned to an airports collection, hotel documents can be assigned to a hotels collection, and so on.

      • Document names must be unique within their collection.

      Use scopes to group multiple collections

      Collections can be assigned to different scopes according to content-type or deployment-phase (for example, test versus production).

      • Collection names must be unique within their scope.

      Browser-Specific Behavior

      Due to IndexedDB requirements, collections and their indexes must be declared when opening the database. Collections cannot be created or deleted while the database is open. This is different from native Couchbase Lite SDKs.

      To modify collections, you must:

      1. Close the database

      2. Reopen it with the new collection configuration

      Default Scopes and Collections

      Every database you create contains a default scope and a default collection named _default.

      If you create a document in the database and don’t specify a specific scope or collection, it is saved in the default collection, in the default scope.

      The default scope and collection cannot be dropped.

      Scope and Collection Naming

      In Couchbase Lite JavaScript, scopes and collections are specified using a combined notation:

      Format

      "scope.collection" or "collection" (implies _default scope)

      Examples

      "inventory.airlines", "inventory.hotels", "tasks" (same as "_default.tasks")

      Naming conventions:

      • Must be between 1 and 251 characters in length

      • Can only contain the characters A-Z, a-z, 0-9, and the symbols _, -, and %

      • Cannot start with _ or % (except for the reserved _default scope and collection)

      • Scope and collection names are case sensitive

      Declare Collections

      Collections must be declared in the DatabaseConfig when opening the database.

      Example 1. Declare collections at database open
      interface TravelAppSchema {
          'inventory.airline': Ariline;
          'inventory.hotel': Hotel;
      }
      
      const travelConfig: DatabaseConfig<TravelAppSchema> = {
          name: 'travel',
          version: 1,
          collections: {
              'inventory.airline': {
                  indexes: ['name', 'icao']
              },
              'inventory.hotel': {
                  indexes: ['country', 'city']
              }
          }
      };
      
      const travelDatabase = await Database.open(travelConfig);
      1 Database configuration
      2 Collections with custom scope using dot notation
      3 Indexes for each collection
      4 Open database with configuration

      Access Collections

      Once declared, you access collections through the database.collection object:

      Example 2. Access collections
      const tasks = database.collections.tasks;
      const users = database.collections.users;
      const inventoryAirlines = travelDatabase.collections['inventory.airline'];
      1 Access collections in default scope using dot notation
      2 Access collection in custom scope using bracket notation
      When accessing collections with custom scopes, use bracket notation with the full "scope.collection" string: database.collection['scope.collection']

      Collection Configuration

      Each collection can have its own configuration when declared:

      Example 3. Configure collections
      const database = await Database.open('secure-app', {
        password: 'encryption-password',
        collections: {
          // Collection with default configuration
          tasks: {},
      
          // Collection with indexes (indexed properties are not encrypted)
          users: {
            indexes: ['username', 'email', 'role']
          },
      
          // Collection in custom scope with configuration
          'private.documents': {
            indexes: ['type', 'category', 'createdAt']
          }
        }
      });
      
      // Access configured collections
      const users = database.collection.users;
      const privateDocuments = database.collection['private.documents'];
      1 Default configuration (all properties encrypted if database has password)
      2 Specify properties to leave unencrypted (can be indexed)
      3 Custom scope collection with configuration

      Add Collections

      To add new collections, you must close and reopen the database with the updated configuration:

      Example 4. Add a collection
      await database.close();
      
      const updatedConfig: DatabaseConfig<AppSchema> = {
          name: 'myapp',
          version: 2, // Increment version
          collections: {
              tasks: {},
              users: {},
              projects: {} // New collection
          }
      };
      
      const updatedDb = await Database.open(updatedConfig);
      1 Close the database
      2 Increment version number
      3 Add new collection to configuration
      4 Reopen database with new collection
      All existing collections must be included when reopening. Omitting a collection from the configuration will make it inaccessible (though its data remains in IndexedDB).

      Remove Collections

      To remove a collection, close the database and reopen without that collection in the configuration:

      Example 5. Remove a collection
      // Database with three collections
      const database = await Database.open('myapp', {
        collections: {
          tasks: {},
          users: {},
          archived: {}
        }
      });
      
      // Close the database
      await database.close();
      
      // Reopen without the 'archived' collection
      const updatedDatabase = await Database.open('myapp', {
        collections: {
          tasks: {},
          users: {}
          // 'archived' collection omitted
        }
      });
      
      // The 'archived' collection is no longer accessible
      console.log('Collection removed from configuration');
      1 Original collections including 'archived'
      2 Reopen without 'archived'
      3 Collection no longer accessible
      Removing a collection from the configuration does not delete its data from IndexedDB. The data remains but is inaccessible. To permanently delete the collection’s data, you must delete the documents before removing the collection from the configuration.

      Purge Collection Data

      To permanently delete a collection’s data:

      Purging deletes all traces of a document, without leaving a "tombstone" revision behind. However, this means purges are not visible to the replicator, which has two side effects:
      • A push replication will not push the deletion to a server.

      • If the document is later updated on the server side, the next pull replication will download the new revision.

      Example 6. Purge collection data before removing
      const database = await Database.open('myapp', {
        collections: {
          tasks: {},
          archived: {}
        }
      });
      
      // Get all documents in the collection
      const archived = database.collection.archived;
      const query = database.createQuery('SELECT META().id FROM archived');
      const results = await query.execute();
      
      // Purge all documents
      for (const row of results) {
        const docId = row.id;
        await archived.purge(docId);
      }
      
      console.log('All documents purged from archived collection');
      
      // Now close and reopen without the collection
      await database.close();
      const updatedDatabase = await Database.open('myapp', {
        collections: {
          tasks: {}
          // 'archived' removed after purging its data
        }
      });
      1 Query all document IDs in the collection
      2 Purge each document
      3 Reopen without the collection

      Index a Collection

      Indexes must be declared in the DatabaseConfig when opening the database, similar to collections:

      Example 7. Index a collection
      const config: DatabaseConfig = {
          name: 'myapp',
          version: 1,
          collections: {
              tasks: {
                  indexes: ['title', 'completed', 'createdAt']
              }
          }
      };
      
      const database = await Database.open(config);
      1 Define indexes in collection configuration
      2 Properties to index

      See Indexing for comprehensive information on creating and using indexes.

      List Scopes and Collections

      You can retrieve a list of all scopes and their collections:

      Example 8. List scopes and collections
      const collectionNames = database.collectionNames;
      for (const name of collectionNames) {
          console.log('Collection:', name);
      }
      1 Get all collection names from database

      Get a Specific Collection

      To get a collection by its full name:

      Example 9. Get a collection
      // Get collection from default scope
      const tasks = database.collection.tasks;
      
      // Get collection from custom scope
      const inventoryAirlines = database.collection['inventory.airlines'];
      
      // Check if collection exists
      if (database.collection['archive.old']) {
        console.log('Collection exists');
      } else {
        console.log('Collection not found');
      }

      Collection Metadata

      You can access metadata about a collection:

      Example 10. Collection metadata
      const tasks = database.collections.tasks;
      const users = database.collections.users;
      const docCount = await tasks.count();
      console.log('Document count:', docCount);

      Using TypeScript Schemas

      TypeScript users can define type-safe schemas for scopes and collections:

      Example 11. TypeScript schema for collections
      interface Task {
          type: 'task';
          title: string;
          completed: boolean;
          priority: number;
          createdAt: string;
      }
      
      // Note: Import as { Blob as CBLBlob } from ‘@couchbase/lite-js’
      // to avoid conflict with the standard Blob type.
      interface User {
          type: 'user';
          username: string;
          email: string;
          role: string;
          avatar: CBLBlob | null;
      }
      
      // Define database schema
      interface AppSchema {
          tasks: Task;
          users: User;
      }

      Troubleshooting

      Collection Not Accessible

      Problem: Collection exists but cannot be accessed

      Solutions:

      • Verify collection was declared in DatabaseConfig

      • Check for typos in collection name

      • Use correct notation for custom scopes ('scope.collection')

      • Use bracket notation for custom scope collections

      Cannot Modify Collections While Open

      Problem: Need to add or remove collections

      Solutions:

      • Close the database first: await database.close()

      • Reopen with updated configuration

      • Ensure all existing collections are included in the new configuration

      Collection Data Not Syncing

      Problem: Documents in collection not syncing with Sync Gateway

      Solutions:

      • Verify replication configuration includes the collection

      • Check Sync Gateway channel access

      • Ensure collection name matches Sync Gateway configuration

      • Review replication filters

      .

      Learn more . . .

      .

      Dive Deeper . . .

      Mobile Forum | Blog | Tutorials

      .