Document Database
The document database (NoSQL) provides JS SDK-style chained calls, and you get an instance via app.database(). It supports create, read, update, and delete operations on collections and documents, complex conditional queries, aggregation, transactions, and more, and is fully aligned with the HTTP API.
- Initialize & Add
- Conditional Query
- Update & Delete
- Transaction
final app = await CloudBase.init(env: 'your-env-id');
final db = app.database();
// Add a single record
final addRes = await db.collection('todos').add({
'title': 'Learn CloudBase',
'completed': false,
'createdAt': DateTime.now(),
});
print('New document ID: ${addRes.id}');
final db = app.database();
final _ = db.command;
final res = await db
.collection('todos')
.where({'completed': false, 'priority': _.inList(['high', 'medium'])})
.orderBy('createdAt', OrderDirection.desc)
.limit(10)
.get();
print('Query results: ${res.data}');
final db = app.database();
final _ = db.command;
// Update a single document, increment a field
await db.collection('todos').doc('doc-id').update({'count': _.inc(1)});
// Delete a single document
await db.collection('todos').doc('doc-id').remove();
final db = app.database();
final _ = db.command;
final transaction = await db.startTransaction();
try {
await transaction.collection('accounts').doc('a').update({'balance': _.inc(-100)});
await transaction.collection('accounts').doc('b').update({'balance': _.inc(100)});
await transaction.commit();
} catch (e) {
await transaction.rollback();
}
database
CloudBaseDatabase app.database({String? instance, String? database})
Gets a document database instance. The optional parameters instance (instance ID) and database (database name) specify the database to access. Both can be omitted, in which case (default) is used (the default database of the default instance). You only need to pass them explicitly when accessing a non-default instance or database.
Parameters
Instance ID, defaults to (default)
Database name, defaults to (default)
Response
Database instance, providing capabilities such as collection, command, Geo, and startTransaction
Example
- Basic Initialization
- Specify Database Configuration
final db = app.database();
final db = app.database(instance: 'my-instance', database: 'my-db');
createCollection
Future<DbCreateCollectionResult> db.createCollection(String collName)
Creates a collection.
Parameters
Collection name
Response
Example
- Create Collection
final result = await db.createCollection('todos');
if (result.isSuccess) {
print('Collection created successfully');
}
collection
CollectionReference db.collection(String collName)
Gets a collection reference, on which you can chain query methods such as where, orderBy, limit, skip, and field, or call doc, add, get, count, and aggregate.
Parameters
Collection name
Response
Collection reference
Example
- Get Collection Reference
- Chained Calls
final collection = db.collection('todos');
final res = await db
.collection('todos')
.where({'completed': false})
.orderBy('createdAt', OrderDirection.desc)
.limit(10)
.get();
add
Future<DbAddResult> collection.add(dynamic data)
Adds records to a collection, supporting single (Map) and batch (List) additions.
Parameters
Document data. Pass a Map for a single addition, or a List for batch addition
Response
Example
- Single Addition
- Batch Addition
final res = await db.collection('todos').add({
'title': 'Learn CloudBase',
'completed': false,
'createdAt': DateTime.now(),
});
print('New document ID: ${res.id}');
final res = await db.collection('todos').add([
{'title': 'Task 1', 'completed': false},
{'title': 'Task 2', 'completed': true},
]);
print('New document ID list: ${res.ids}');
doc
DocumentReference collection.doc(dynamic docId)
Gets a document reference, on which you can call get, update, set, remove, and field.
Parameters
Document ID
Response
Document reference
Example
- Get Document Reference
final docRef = db.collection('todos').doc('doc-id');
final res = await docRef.get();
print(res.data);
where
Query collection.where(Map<String, dynamic> condition)
Sets query conditions, supporting equality matching and complex condition filtering via db.command operators.
Parameters
Query condition object, supporting equality matching, operator matching, nested field matching, and more
Response
Query object, on which you can chain methods such as orderBy, limit, skip, field, get, count, update, and remove
Example
- Basic Query
- Complex Conditional Query
final res = await db
.collection('todos')
.where({'completed': false, 'priority': 'high'})
.get();
print('Query results: ${res.data}');
final _ = db.command;
final res = await db
.collection('todos')
.where({
'age': _.gt(18),
'tags': _.inList(['tech', 'study']),
'createdAt': _.gte(DateTime.now().subtract(const Duration(days: 7))),
})
.orderBy('createdAt', OrderDirection.desc)
.limit(10)
.get();
print('Query results: ${res.data}');
orderBy
Query collection.orderBy(String field, OrderDirection direction)
Sets the sort rule. direction can be OrderDirection.asc or OrderDirection.desc. You can call it multiple times to combine multi-field sorting.
Parameters
Sort field
Sort direction: OrderDirection.asc (ascending) or OrderDirection.desc (descending)
Response
Query object, on which you can continue chaining
Example
- Example
final res = await db
.collection('todos')
.orderBy('createdAt', OrderDirection.desc)
.get();
limit
Query collection.limit(int max)
Sets the maximum number of records to return.
Parameters
Maximum number of records to return
Response
Query object, on which you can continue chaining
Example
- Example
final res = await db.collection('todos').limit(10).get();
skip
Query collection.skip(int offset)
Sets the number of records to skip, commonly used for pagination.
Parameters
Number of records to skip (offset)
Response
Query object, on which you can continue chaining
Example
- Pagination Query
const pageSize = 10;
const pageNum = 2;
final res = await db
.collection('todos')
.orderBy('createdAt', OrderDirection.desc)
.skip((pageNum - 1) * pageSize)
.limit(pageSize)
.get();
print('Page $pageNum data: ${res.data}');
print('Offset: ${res.offset}, page size: ${res.limit}');
field
Query collection.field(Map<String, dynamic> projection)
Specifies the fields to return in the query. true means return, and false means do not return. The document reference doc also supports the field method.
Parameters
Field projection, e.g. {'title': true, 'content': false}
Response
Query object, on which you can continue chaining
Example
- Example
final res = await db
.collection('todos')
.where({'completed': false})
.field({'title': true, 'completed': true, 'content': false})
.get();
get
Future<DbGetResult> collection.get()
Future<DbGetResult> query.get()
Future<DbGetResult> doc.get()
Gets query results. Called on a collection reference, it performs an unconditional query; called on a Query, it returns the list of matching documents; called on a document reference, it returns a single document (data is an empty list when the document does not exist).
Parameters
No parameters
Response
Example
- Query Collection
- Query Single Document
final res = await db.collection('todos').get();
print('${res.data.length} records in total');
final res = await db.collection('todos').doc('doc-id').get();
if (res.data.isNotEmpty) {
print('Document content: ${res.data.first}');
}
count
Future<DbCountResult> collection.count()
Future<DbCountResult> query.count()
Counts the number of documents matching the conditions.
Parameters
No parameters
Response
Example
- Example
final res = await db
.collection('todos')
.where({'completed': false})
.count();
print('Number of incomplete tasks: ${res.total}');
update
Future<DbUpdateResult> query.update(Map<String, dynamic> data)
Future<DbUpdateResult> doc.update(Map<String, dynamic> data, {bool returnDoc = false})
Updates documents. Called on a Query, it batch-updates documents matching the conditions; called on a document reference, it performs a merge update on a single document, and returns the updated document when returnDoc is true.
Parameters
Update data. You can use db.command update operators (such as _.inc, _.set, _.push, etc.)
Supported only by document reference update. When true, returns the updated document. Defaults to false
Response
Example
- Update Single Document
- Batch Update
final _ = db.command;
final res = await db
.collection('todos')
.doc('doc-id')
.update({'count': _.inc(1), 'completed': true}, returnDoc: true);
print('Updated document: ${res.doc}');
final res = await db
.collection('todos')
.where({'completed': false})
.update({'archived': true});
print('${res.updated} records updated');
set
Future<DbUpdateResult> doc.set(Map<String, dynamic> data)
Sets document data (full replacement; creates the document if it does not exist).
Parameters
Full document data, which will completely replace the original document
Response
Example
- Example
final res = await db.collection('todos').doc('doc-id').set({
'title': 'Reset task',
'completed': false,
});
remove
Future<DbRemoveResult> query.remove()
Future<DbRemoveResult> doc.remove()
Deletes documents. Called on a Query, it batch-deletes documents matching the conditions; called on a document reference, it deletes a single document.
Parameters
No parameters
Response
Example
- Delete Single Document
- Batch Delete
final res = await db.collection('todos').doc('doc-id').remove();
print('${res.deleted} records deleted');
final res = await db
.collection('todos')
.where({'completed': true})
.remove();
print('${res.deleted} records deleted');
command
DbCommand get db.command
Gets the query/update command (corresponding to the JS SDK's db.command, commonly abbreviated as _). It supports comparison, logical, field/array, update, geolocation, and other operators.
Parameters
No parameters
Response
Command object, used to build query conditions and update operations
Example
- Comparison & Logical Operators
- Field & Array Operators
- Update Operators
final _ = db.command;
// eq / neq / gt / gte / lt / lte / inList / nin
await db.collection('todos').where({'age': _.gte(18)}).get();
// and / or / not / nor
await db.collection('todos').where({
'priority': _.or([_.eq('high'), _.eq('medium')]),
}).get();
final _ = db.command;
// exists / mod / all / elemMatch / size
await db.collection('todos').where({
'tags': _.all(['tech', 'study']),
'assignee': _.exists(true),
}).get();
final _ = db.command;
// set / remove / inc / mul / min / max / rename / bit
await db.collection('todos').doc('doc-id').update({
'count': _.inc(1),
'weight': _.mul(2),
'deprecatedField': _.remove(),
});
// Array updates: push / pop / shift / unshift / pull / pullAll / addToSet
await db.collection('todos').doc('doc-id').update({
'tags': _.push('new tag'),
'members': _.addToSet('user-1'),
});
aggregate
Aggregate collection.aggregate()
Gets an aggregation operation object. Chain aggregation stages and then call end() to execute. Supports match, group, sort, project, limit, skip, unwind, lookup, addFields, count, sample, bucket, bucketAuto, geoNear, replaceRoot, sortByCount, and custom stage.
Parameters
No parameters
Response
Aggregation operation object. Chain stages and then call end() to execute
Example
- Grouped Statistics
final res = await db
.collection('todos')
.aggregate()
.match({'completed': true})
.group({
'_id': '\$priority',
'total': {'\$sum': 1},
})
.sort({'total': -1})
.end();
print('Aggregation results: ${res.data}');
startTransaction
Future<Transaction> db.startTransaction()
Starts a transaction and returns a transaction object. Use the transaction object's collection to get a collection reference within the transaction to operate on, and finally call commit to commit or rollback to roll back.
Parameters
No parameters
Response
Example
- Transfer Transaction
final _ = db.command;
final transaction = await db.startTransaction();
try {
await transaction.collection('accounts').doc('a').update({'balance': _.inc(-100)});
await transaction.collection('accounts').doc('b').update({'balance': _.inc(100)});
await transaction.commit();
} catch (e) {
await transaction.rollback();
}
runCommands
Future<DbRunCommandsResult> db.runCommands({required List<Map<String, dynamic>> commands, String? transactionId})
Executes MongoDB-style database commands (in batch). Callable by administrators only.
Parameters
Array of command objects
Transaction ID (optional, executes all commands within the transaction)
Response
Example
- Example
final res = await db.runCommands(commands: [
{'find': 'todos', 'filter': {'completed': true}},
]);
print('Execution results: ${res.list}');
Geo
GeoNamespace get db.Geo
DbRegExp db.RegExp({required String regexp, String? options})
DbServerDate db.serverDate({int offset = 0})
Database helper types: the geolocation namespace Geo, the regular expression RegExp, and the server-side time serverDate.
Geosupportspoint,lineString,polygon,multiPoint,multiLineString, andmultiPolygon, used together with the operatorsgeoNear,geoWithin, andgeoIntersects.RegExpis used for fuzzy queries;optionssuch asimeans case-insensitive.serverDategenerates server-side time, whereoffsetis the offset in milliseconds.
Parameters
No parameters
Response
Geolocation namespace
Example
- Geolocation Query
- Regex Fuzzy Query
- Server-side Time
final _ = db.command;
// Query records within 5000 meters of the specified coordinates
// geoNear only supports the geometry, maxDistance and minDistance options and does not support limiting the number of returned records via an option (for example limit: 10)
// To limit the results, chain limit() after where(), such as the trailing .limit(10)
final res = await db.collection('places').where({
'location': _.geoNear(
geometry: db.Geo.point(116.397, 39.908),
maxDistance: 5000,
),
}).limit(10).get();
final res = await db.collection('todos').where({
'title': db.RegExp(regexp: 'study', options: 'i'),
}).get();
// Write the current server-side time
await db.collection('todos').add({
'title': 'Task',
'createdAt': db.serverDate(),
});