database
Overview
Database API provides a complete set of document database operation features, supporting CRUD operations, complex queries, aggregation, location query, and transaction operations.
Database API is divided into the following categories by feature purpose:
-Initialization: Get database instance
- Collection method: Get collection reference and create a collection
- Document method: Get document reference
- Newly added data: Add single or multiple data entries to the collection
- Query data: Support single query, conditional query, paging query, aggregate query and location query.
- Update data: Support single-entry update, batch update and update or create operations.
- Delete data: Support single deletion and delete in batches.
- Operators: Query operator and update operator.
- Transaction operations: Support activation, submission and rollback of transactions.
- Monitor in real time: Support real-time listening for document or query result changes.
- Advanced operations: Execute native MongoDB commands.
Basic usage example
Publishable Key can go to Cloud Development Platform/API Key Configuration to generate
import cloudbase from "@cloudbase/js-sdk";
// Initialize it.
const app = cloudbase.init({
env: "your-env-id", // Replace this value with your environment ID
region: "ap-shanghai", // Region, defaults to Shanghai
accessKey: "", // Fill in the generated Publishable Key
});
// Get database reference
const db = app.database();
// Get query command
const _ = db.command;
// Get position type
const Geo = db.Geo;
Add a new record to the collection.
async function addTodo() {
const result = await db.collection("todos").add({
title: "Learn CloudBase"
content: "Complete the database operation tutorial"
completed: false,
priority: "high",
createdAt: new Date(),
tags: ["study", "technology"],
});
console.log("successful addition, document ID:", result.id);
}
// Add new record with specified document ID (use set)
async function addTodoWithId() {
const result = await db.collection("todos").doc("custom-id").set({
title: "Task with specified ID",
completed: false,
createdAt: new Date(),
});
console.log("successful addition");
}
// Query data within the collection
async function queryTodos() {
const _ = db.command;
// Conditional query: Incomplete high-priority task
const result = await db
.collection("todos")
.where({
completed: false,
priority: "high",
})
.orderBy("createdAt", "desc")
.limit(10)
.get();
console.log("query result:", result.data);
// Complex queries: Using operators
const complexResult = await db
.collection("todos")
.where({
// priority is high or medium
priority: _.in(["high", "medium"]),
Created in the last 7 days
createdAt: _.gte(new Date(Date.now() - 7 * 24 * 60 * 60 * 1000)),
})
.field({
title: true,
priority: true,
createdAt: true,
})
.get();
console.log("complex query result:", complexResult.data);
}
// Update the specified document
async function updateTodo(todoId) {
const result = await db.collection("todos").doc(todoId).update({
completed: true,
updatedAt: new Date(),
});
console.log("update succeeded, number of records impacted:", result.updated);
}
// Update with operators
async function updateWithOperators(todoId) {
const _ = db.command;
const result = await db
.collection("todos")
.doc(todoId)
.update({
viewCount: _.inc(1)
viewCount: _.inc(1),
// Add a new tag (non-repetitive)
tags: _.addToSet("important"),
Update Time
updatedAt: new Date(),
});
console.log("Update successful");
}
// Delete specified document
async function deleteTodo(todoId) {
const result = await db.collection("todos").doc(todoId).remove();
console.log(
"Deleted successfully, number of records impacted:",
result.deleted
);
}
// Delete with conditions
async function deleteCompletedTodos() {
const result = await db
.collection("todos")
.where({
completed: true,
})
.remove();
console.log(
"Completed task deleted, number of records impacted:",
result.deleted
);
}
// Batch update: change ALL low-priority tasks to ordinary priority
async function batchUpdate() {
const result = await db
.collection("todos")
.where({
priority: "low",
})
.update({
priority: "normal",
updatedAt: new Date(),
});
console.log("batch update succeeded, number of records impacted:", result.updated);
}
Delete in batches: Delete tasks completed 30 days ago.
async function batchDelete() {
const _ = db.command;
const result = await db
.collection("todos")
.where({
completed: true,
createdAt: _.lt(new Date(Date.now() - 30 * 24 * 60 * 60 * 1000)),
})
.remove();
console.log("Deleted in batches successfully, number of records impacted:", result.deleted);
}
// Paging query example
async function paginatedQuery(pageNum = 1, pageSize = 10) {
const result = await db
.collection("todos")
.where({
completed: false,
})
.orderBy("createdAt", "desc")
.skip((pageNum - 1) * pageSize)
.limit(pageSize)
.get();
console.log(`Page ${pageNum} data:`, result.data);
console.log("Current page count:", result.data.length);
return {
data: result.data,
pageNum,
pageSize,
};
}
// Get the total count used to calculate the total number of pages
async function getTotalCount() {
const result = await db
.collection("todos")
.where({
completed: false,
})
.count();
console.log("total record count:", result.total);
return result.total;
}
// Aggregation statistics example
async function aggregateStats() {
// Count the statistical quantity by priority grouping
const result = await db
.collection("todos")
.aggregate()
.group({
_id: "$priority",
count: { $sum: 1 },
})
.sort({
count: -1,
})
.end();
console.log("count by priority:", result.data);
// Output: [{ _id: 'high', count: 15 }, { _id: 'normal', count: 30 }, ...]
// Count the number of completed and ongoing tasks
const statusResult = await db
.collection("todos")
.aggregate()
.group({
_id: "$completed",
count: { $sum: 1 },
})
.end();
console.log("status statistics:", statusResult.data);
}
// Monitor data change in real time
function watchTodos() {
const listener = db
.collection("todos")
.where({
completed: false,
})
.orderBy("createdAt", "desc")
.limit(20)
.watch({
onChange: (snapshot) => {
console.log("data change:", snapshot.type);
if (snapshot.type === "init") {
// Initialize the data
console.log("initial data:", snapshot.docs);
} else {
// Incremental adjustment
snapshot.docChanges.forEach((change) => {
switch (change.dataType) {
case "add":
console.log("add document:", change.doc);
break;
case "update":
console.log("update document:", change.doc);
break;
case "remove":
console.log("delete document:", change.docId);
break;
}
});
}
},
onError: (error) => {
console.error("Listen error:", error);
},
});
// Return listener for subsequent close
return listener;
}
// Usage example
const listener = watchTodos();
// Close listener when needed
// listener.close();
// Complete error handling example
async function safeDbOperation() {
try {
// Query operation
const result = await db
.collection("todos")
.where({ completed: false })
.get();
console.log("query succeeded:", result.data);
return { success: true, data: result.data };
} catch (error) {
// Error Handling
console.error("Database operation failed:", error);
switch (error.code) {
case "PERMISSION_DENIED":
console.error(
"Insufficient permissions, please check security rule configuration"
);
break;
case "INVALID_PARAM":
console.error("Parameter error, check query condition");
break;
case "DATABASE_NOT_FOUND":
console.error("Database or collection not found");
break;
case "NETWORK_ERROR":
console.error("Network error, check the network");
break;
default:
console.error("Unknown error:", error.message);
}
return { success: false, error: error.message };
}
}
//Operation with retry
async function retryOperation(operation, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await operation();
} catch (error) {
console.warn(`Operation failed, retry ${i + 1}...`);
if (i === maxRetries - 1) throw error;
//Wait and retry later
await new Promise((resolve) => setTimeout(resolve, 1000 * (i + 1)));
}
}
}
Initialization
database
app.database(config?: IDbConfig): Database
Get database instance for follow-up database operation. Visit Cloud Development Platform/document database for instance information retrieval.

参数
Database configuration object (optional)
返回
Database instance object, callable attributes and methods such as collection(), command, Geo, and serverDate()
示例
import cloudbase from "@cloudbase/js-sdk";
// Initialize the application
const app = cloudbase.init({
env: "your-env-id", // Replace this value with your environment ID
region: "ap-shanghai", // Region, defaults to Shanghai
accessKey: "", // Fill in the generated Publishable Key
});
// Get database reference (use default configuration)
const db = app.database();
// Get query command
const _ = db.command;
// Get position type
const Geo = db.Geo;
// Specify the instance ID and database name
const db = app.database({
instance: "your-instance-id", // Instance ID
database: "your-database-name", // Database name
});
Collection Methods
createCollection
async db.createCollection(collName: string): Promise<ICreateCollectionResult>
Create a collection.
参数
Collection Name
返回
Creation result
示例
Create a new collection
const result = await db.createCollection("new-collection");
console.log("Collection created successfully");
collection
db.collection(collName: string): CollectionReference
Retrieve collection reference for subsequent data operations.
参数
Collection Name
返回
Collection reference object, can use chained call doc(), where(), add(), aggregate() methods
示例
// Get collection reference
const todosCollection = db.collection("todos");
// Query data within the collection
const result = await todosCollection.get();
console.log("query result:", result.data);
// Perform a conditional query with a chained call
const result = await db
.collection("todos")
.where({ completed: false })
.orderBy("createdAt", "desc")
.limit(10)
.get();
console.log("query result:", result.data);
Document method
doc
doc(docId: string | number): DocumentReference
Get a document reference by document ID for follow-up queries, updates, or deletion.
参数
Unique identifier of the document, supports string or number data type
返回
Document reference object, can use chained call get(), update(), set(), remove(), field() methods
示例
Query a single record by document ID.
const result = await db.collection("todos").doc("todo-id-123").get();
if (result.data && result.data.length > 0) {
console.log("query result:", result.data[0]);
} else {
console.log("document not found");
}
Only return specified field
const result = await db
.collection("todos")
.doc("todo-id-123")
.field({
title: true,
completed: true,
// Do not return the content field
content: false,
})
.get();
console.log("query result:", result.data);
//Return result format
{
data: [
{
_id: "todo-id-123",
title: "Learn CloudBase"
content: "Complete the database operation tutorial"
completed: false,
priority: "high",
createdAt: "2024-01-15T08:00:00.000Z",
tags: ["study", "technology"],
},
],
requestId: "xxx-xxx-xxx"
}
Add data
add
async add(data: object): Promise<AddResult>
Add a new record to the collection.
-Add a single data record to the specified collection -Support automatic generation of document IDs, or specify a document ID
- Support the geographic location data type
参数
The data object to be added, supporting nested objects, arrays, geographic locations and other data types
返回
示例
// Add a single record
const result = await db.collection("todos").add({
title: "Learn CloudBase"
content: "Complete the database operation tutorial"
completed: false,
priority: "high",
createdAt: new Date(),
tags: ["study", "technology"],
});
console.log("successful addition, document ID:", result.id);
Add record with specified document ID
const result = await db.collection("todos").doc("custom-id-123").set({
title: "Task with specified ID",
completed: false,
createdAt: new Date(),
});
console.log("successful addition, document ID:", result.upsertedId || "custom-id-123");
// Create a GeoPoint
const point = new db.Geo.Point(116.404, 39.915);
// Create a geographic path
const line = new db.Geo.LineString([
new db.Geo.Point(116.404, 39.915),
new db.Geo.Point(116.405, 39.916),
]);
// Create a geographic region (the polygon must close)
const polygon = new db.Geo.Polygon([
new db.Geo.LineString([
new db.Geo.Point(116.404, 39.915),
new db.Geo.Point(116.405, 39.915),
new db.Geo.Point(116.405, 39.916),
new db.Geo.Point(116.404, 39.915), // Close point
]),
]);
// Add records with GeoPoint
const result = await db.collection("locations").add({
name: "Beijing Tiananmen",
location: point,
path: line,
area: polygon,
createdAt: new Date(),
});
console.log("successful addition, document ID:", result.id);
try {
const result = await db.collection("todos").add({
title: "New Task"
completed: false,
});
console.log("successful addition, document ID:", result.id);
} catch (error) {
console.error("Addition failed:", error.message);
// Common error handling
if (error.code === "PERMISSION_DENIED") {
console.error("Insufficient permissions, please check security rule configuration");
} else if (error.code === "INVALID_PARAM") {
console.error("Parameter error, check data format");
}
}
Query data
get
async get(): Promise<GetResult>
Get query results, return the document list that matches the condition.
-Return up to 100 records by default
- Support returning a maximum of 1000 records (set via limit).
参数
无参数
返回
示例
// Get all documents in the collection (default max 100)
const result = await db.collection("todos").get();
console.log("query result:", result.data);
console.log("total:", result.total);
// Conditional query
const result = await db
.collection("todos")
.where({ completed: false })
.orderBy("createdAt", "desc")
.limit(20)
.skip(0)
.get();
console.log("data:", result.data);
console.log("total:", result.total);
console.log("limit:", result.limit);
console.log("offset:", result.offset);
where
where(condition: object): Query
Set query conditions, support various operators to perform complex condition filtering.
-Query condition must be object type -The value of the condition object cannot all be undefined
参数
The query condition object, supporting equivalent matching, operator matching, nested field matching and other types
返回
Query object, can use chained call orderBy(), limit(), skip(), field(), get(), count(), update(), remove() methods
示例
// Query all incomplete high-priority tasks
const result = await db
.collection("todos")
.where({
completed: false,
priority: "high",
})
.get();
console.log("query result:", result.data);
const _ = db.command;
// Perform complex queries using operators
const result = await db
.collection("todos")
.where({
// Age above 18
age: _.gt(18),
// Tag contains 'technology' or 'study'
tags: _.in(["technology", "study"]),
Created in the last week
createdAt: _.gte(new Date(Date.now() - 7 * 24 * 60 * 60 * 1000)),
})
.orderBy("createdAt", "desc")
.limit(10)
.get();
console.log("query result:", result.data);
// Paging query example
const pageSize = 10;
const pageNum = 1;
const result = await db
.collection("todos")
.where({
completed: false,
})
.orderBy("createdAt", "desc")
.skip((pageNum - 1) * pageSize)
.limit(pageSize)
.get();
console.log("Page", pageNum, "data:", result.data);
console.log("total record count:", result.total);
console.log("current page offset:", result.offset);
console.log("current page limit:", result.limit);
Only return specified field
const result = await db
.collection("todos")
.where({
completed: false,
})
.field({
title: true,
completed: true,
createdAt: true,
// Do not return the content field
content: false,
})
.get();
console.log("query result:", result.data);
count
async count(): Promise<CountResult>
Statistics of the number of documents that match the condition.
参数
无参数
返回
示例
// Count the number of unfinished tasks
const result = await db.collection("todos").where({ completed: false }).count();
console.log("unfinished tasks:", result.total);
orderBy
orderBy(fieldPath: string, direction: 'asc' | 'desc'): Query
Set the sorting method of query results.
参数
Sorting field path
Sorting order: asc ascending order, desc descending order
返回
Query object, can proceed with chained call
示例
// Sort by creation time in descending order
const result = await db.collection("todos").orderBy("createdAt", "desc").get();
// Multi-field sorting
const result = await db
.collection("todos")
.orderBy("priority", "desc")
.orderBy("createdAt", "asc")
.get();
limit
limit(max: number): Query
Set the maximum record count returned by the query.
- Default limit: 100 -supports up to 1000
参数
Maximum return record count, must be a positive integer, maximum value of 1000
返回
Query object, can proceed with chained call
示例
// Only get the first 10 records
const result = await db.collection("todos").limit(10).get();
skip
skip(offset: number): Query
Set the query result offset for pagination queries.
参数
Offset, must be a non-negative integer
返回
Query object, can proceed with chained call
示例
// Skip the first 20 records, get records 21-30
const result = await db.collection("todos").skip(20).limit(10).get();
field
field(projection: object): Query | DocumentReference
Specify the fields to return.
参数
Field projection object. true means return this field, false means do not return
返回
Query object or document reference, can proceed with chained call
示例
Only return title and completed fields
const result = await db
.collection("todos")
.field({
title: true,
completed: true,
})
.get();
// Exclude the content field
const result = await db
.collection("todos")
.field({
content: false,
})
.get();
aggregate
aggregate(): Aggregate
Get the aggregation object for execution of aggregate queries, supporting aggregation stages such as group, match, sort, and project.
Refer to the aggregate query for aggregation grammar.
参数
无参数
返回
Aggregation object supporting chained calls of various aggregation stage methods
示例
// Count the number of tasks by priority
const result = await db
.collection("todos")
.aggregate()
.group({
_id: "$priority",
count: {
$sum: 1,
},
})
.end();
console.log("count by priority:", result.data);
// Output: [{ _id: 'high', count: 5 }, { _id: 'normal', count: 10 }, ...]
// Count the number of unfinished tasks and the average priority
const result = await db
.collection("todos")
.aggregate()
.match({
completed: false,
})
.group({
_id: null,
totalCount: { $sum: 1 },
avgPriority: { $avg: "$priorityValue" },
})
.end();
console.log("statistical result:", result.data);
// Complex aggregation: group statistics by date and sort
const result = await db
.collection("todos")
.aggregate()
.match({
createdAt: {
$gte: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000),
},
})
.group({
_id: {
$dateToString: {
format: "%Y-%m-%d",
date: "$createdAt",
},
},
count: { $sum: 1 },
})
.sort({
_id: -1,
})
.end();
console.log("statistics by date:", result.data);
// Supported aggregation stage methods:
// - addFields: Add new field
// - bucket: Bucket
// - bucketAuto: Auto Bucketing
// - count: Count
// - geoNear: Nearby geolocation query
// - group: Group
// - limit: Limit quantity
// - lookup: Table join query
// - match: Conditional filtering
// - project: Field projection
// - replaceRoot: Replace root document
// - sample: Random sampling
// - skip: Skip count
// - sort: Sort
// - sortByCount: Sort by quantity
// - unwind: Unfold array
const result = await db
.collection("orders")
.aggregate()
.lookup({
from: "users",
localField: "userId",
foreignField: "_id",
as: "userInfo",
})
.unwind("$userInfo")
.project({
orderId: 1,
amount: 1,
"userInfo.name": 1,
})
.end();
Geolocation query
Support spatial querying for geolocation fields, including nearby queries, region queries, and intersect queries.
When querying a geolocation field, create a geo-indexing, otherwise the query will fail
参数
Nearby queries, return results sorted by distance
Region query, return results within the specified region
Intersect query, return results that intersect with the specified geometric shape
返回
Query object, can use chained call get() method to obtain result
示例
const _ = db.command;
// Query nearby users (sorted by distance)
const result = await db
.collection("users")
.where({
location: _.geoNear({
geometry: new db.Geo.Point(116.404, 39.915), // Tiananmen coordinate
maxDistance: 1000, // Maximum distance 1000 meters
minDistance: 0, // minimum distance 0 meters
}),
})
.get();
console.log("nearby users:", result.data);
const _ = db.command;
// Define the query region (polygon)
const polygon = new db.Geo.Polygon([
new db.Geo.LineString([
new db.Geo.Point(116.4, 39.91),
new db.Geo.Point(116.41, 39.91),
new db.Geo.Point(116.41, 39.92),
new db.Geo.Point(116.4, 39.92),
new db.Geo.Point(116.4, 39.91), // Close
]),
]);
// Query users within the specified region
const result = await db
.collection("users")
.where({
location: _.geoWithin({
geometry: polygon,
}),
})
.get();
console.log("users in the region:", result.data);
const _ = db.command;
// Define query path
const line = new db.Geo.LineString([
new db.Geo.Point(116.404, 39.915),
new db.Geo.Point(116.405, 39.916),
]);
// Query records that intersect with the path
const result = await db
.collection("routes")
.where({
path: _.geoIntersects({
geometry: line,
}),
})
.get();
console.log("intersect records:", result.data);
// Supported position types
const Geo = db.Geo;
// Point - Point
const point = new Geo.Point(116.404, 39.915); // (longitude, latitude)
// LineString - line segment (at least 2 points)
const lineString = new Geo.LineString([
new Geo.Point(116.404, 39.915),
new Geo.Point(116.405, 39.916),
]);
// Polygon - polygon (must close)
const polygon = new Geo.Polygon([
new Geo.LineString([
new Geo.Point(116.404, 39.915),
new Geo.Point(116.405, 39.915),
new Geo.Point(116.405, 39.916),
new Geo.Point(116.404, 39.915), // Close point
]),
]);
// MultiPoint - Multi-point
const multiPoint = new Geo.MultiPoint([
new Geo.Point(116.404, 39.915),
new Geo.Point(116.405, 39.916),
]);
// MultiLineString - Multi-line segment
const multiLineString = new Geo.MultiLineString([
new Geo.LineString([
new Geo.Point(116.404, 39.915),
new Geo.Point(116.405, 39.916),
]),
]);
// MultiPolygon - MULTIPOLYGON
const multiPolygon = new Geo.MultiPolygon([polygon]);
Update data
update
async update(data: object): Promise<UpdateResult>
Update document data. Single-entry update and batch update are supported.
-Update a single record via doc().update()
- Update multiple records in batch via
where().update()-Supports the use of update operators to perform complex updates -Cannot update the_idfield
参数
The data object to be updated, supporting updates to common fields and operators
返回
示例
// Update the specified document
const result = await db.collection("todos").doc("todo-id-123").update({
title: "Learn CloudBase Database"
completed: true,
updatedAt: new Date(),
completedBy: "user123",
});
console.log("update succeeded, number of records impacted:", result.updated);
// Update multiple records in batch
const result = await db
.collection("todos")
.where({
completed: false,
priority: "low",
})
.update({
priority: "normal",
updatedAt: new Date(),
});
console.log(
"batch update succeeded, number of records impacted:",
result.updated
);
const _ = db.command;
// Update with operators
const result = await db
.collection("todos")
.doc("todo-id-123")
.update({
// Numeric value increment
viewCount: _.inc(1),
// Add an element to the array
tags: _.push("new tag"),
// Delete field
tempField: _.remove(),
//Set field (create if not present)
metadata: _.set({
lastModified: new Date(),
modifiedBy: "user123",
}),
});
console.log("Update successful");
try {
const result = await db.collection("todos").doc("todo-id-123").update({
completed: true,
});
if (result.updated === 0) {
console.log("no matching document found");
} else {
console.log(
"update succeeded, number of records impacted:",
result.updated
);
}
} catch (error) {
console.error("update failed:", error.message);
if (error.code === "PERMISSION_DENIED") {
console.error(
"Insufficient permissions, please check security rule configuration"
);
}
}
set
async set(data: object): Promise<SetResult>
Set document data, if the document does not exist create a new document.
-Unlike update(), set() replaces document content
-Suitable for scenarios where refresh or create is required.
-Cannot contain update operators
-Cannot update the _id field
参数
The data object to be set will replace all existing document content and cannot contain update operators
返回
示例
// Update the document, if it does not exist create
const result = await db.collection("todos").doc("todo-id-123").set({
title: "New Task",
completed: false,
priority: "high",
createdAt: new Date(),
});
if (result.upsertedId) {
console.log("create new document, ID:", result.upsertedId);
} else {
console.log(
"update existing document, number of records impacted:",
result.updated
);
}
// set replaces document content
// original document: { _id: '123', title: 'A', content: 'xxx', tags: ['a'] }
const result = await db.collection("todos").doc("123").set({
title: "B",
completed: true,
});
// document after update: { _id: '123', title: 'B', completed: true }
// Note: The content and tags fields are removed
Delete data
remove
async remove(): Promise<RemoveResult>
Delete document. Support single deletion and delete in batches.
-Delete a single record with doc().remove()
- Delete multiple records in batch via
where().remove()
When deleting in batches, the offset, limit, projection, and orderBy parameters will be ignored.
参数
无参数
返回
示例
// Delete specified document
const result = await db.collection("todos").doc("todo-id-123").remove();
console.log(
"Deleted successfully, number of records impacted:",
result.deleted
);
const _ = db.command;
Delete in batches: Delete tasks completed 30 days ago.
const result = await db
.collection("todos")
.where({
completed: true,
createdAt: _.lt(new Date(Date.now() - 30 * 24 * 60 * 60 * 1000)),
})
.remove();
console.log("Deleted in batches successfully, number of records impacted:", result.deleted);
const _ = db.command;
Delete all low-priority completed tasks
const result = await db
.collection("todos")
.where({
completed: true,
priority: _.in(["low", "none"]),
})
.remove();
console.log("Conditional deletion successful, number of records impacted:", result.deleted);
try {
const result = await db.collection("todos").doc("todo-id-123").remove();
if (result.deleted === 0) {
console.log("no matching document found");
} else {
console.log(
"Deleted successfully, number of records impacted:",
result.deleted
);
}
} catch (error) {
console.error("Delete failed:", error.message);
if (error.code === "PERMISSION_DENIED") {
console.error(
"Insufficient permissions, please check security rule configuration"
);
}
}
Operator
Query operator
Get the query operator via db.command to build complex query conditions.
参数
返回
无参数
示例
const _ = db.command;
Equal to
db.collection("users").where({ age: _.eq(18) });
Not equal to
db.collection("users").where({ status: _.neq("deleted") });
Greater than, greater than or equal to
db.collection("users").where({ age: _.gt(18) });
db.collection("users").where({ age: _.gte(18) });
Less than, less than or equal to
db.collection("users").where({ age: _.lt(60) });
db.collection("users").where({ age: _.lte(60) });
// In the array
db.collection("users").where({ role: _.in(["admin", "editor"]) });
Not in the array
db.collection("users").where({ status: _.nin(["banned", "deleted"]) });
const _ = db.command;
AND: satisfy multiple conditions at the same time
db.collection("users").where({
age: _.and(_.gt(18), _.lt(60)),
});
OR: satisfy any of the conditions
db.collection("users").where({
role: _.or(_.eq("admin"), _.eq("editor")),
});
// NOT: Perform a negation operation.
db.collection("users").where({
status: _.not(_.eq("deleted")),
});
// Used in combination
db.collection("users").where(
_.or([{ age: _.gt(60) }, { role: _.eq("admin") }])
);
// nor: none satisfied
db.collection("users").where(
_.nor([{ status: "banned" }, { status: "deleted" }])
);
const _ = db.command;
// field exists
db.collection("users").where({
avatar: _.exists(true),
});
// Modulo operation (search even)
db.collection("users").where({
age: _.mod([2, 0]),
});
// The array contains all specified elements
db.collection("articles").where({
tags: _.all(["javascript", "nodejs"]),
});
// Array element match
db.collection("orders").where({
items: _.elemMatch({
price: _.gt(100),
quantity: _.gte(2),
}),
});
// Array length
db.collection("articles").where({
tags: _.size(3),
});
Update operator
Get the update operator via db.command for execution of complex update operations.
参数
返回
无参数
示例
const _ = db.command;
//Set field value
db.collection("users")
.doc("user-id")
.update({
profile: _.set({ name: "Zhang San", age: 25 }),
});
// Delete field
db.collection("users").doc("user-id").update({
tempData: _.remove(),
});
// Numeric value increment
db.collection("articles")
.doc("article-id")
.update({
viewCount: _.inc(1),
likeCount: _.inc(5),
});
// Numeric value multiplication
db.collection("products")
.doc("product-id")
.update({
price: _.mul(0.9), // 10% off
});
// Get the minimum/maximum value
db.collection("users")
.doc("user-id")
.update({
minScore: _.min(60),
maxScore: _.max(100),
});
// Rename field
db.collection("users")
.doc("user-id")
.update({
oldField: _.rename("newField"),
});
// Bitwise Operation
db.collection("users")
.doc("user-id")
.update({
flags: _.bit({ and: 5 }), // Bitwise AND operation
});
const _ = db.command;
// Add at the end of the array
db.collection("articles")
.doc("article-id")
.update({
tags: _.push("new tag"),
});
Add multiple elements
db.collection("articles")
.doc("article-id")
.update({
tags: _.push(["tag1", "tag2"]),
});
// Advanced push (user-specified location, sorting order, truncation)
db.collection("articles")
.doc("article-id")
.update({
tags: _.push({
each: ["tag1", "tag2"]
position: 0, // insertion position
sort: 1, // Sort
slice: 10, // Take the first 10
}),
});
Remove the first/last element of an array
db.collection("articles").doc("article-id").update({
tags: _.pop(), // Remove the last element
});
db.collection("articles").doc("article-id").update({
tags: _.shift(), // Remove the first element
});
// Add at the beginning of the array
db.collection("articles")
.doc("article-id")
.update({
tags: _.unshift("pin to top tag"),
});
Remove matching elements
db.collection("articles")
.doc("article-id")
.update({
tags: _.pull("tag to delete"),
});
Remove multiple matching elements
db.collection("articles")
.doc("article-id")
.update({
tags: _.pullAll(["tag1", "tag2"]),
});
Add distinct elements
db.collection("articles")
.doc("article-id")
.update({
tags: _.addToSet("unique tag"),
});
const _ = db.command;
// Complex update operation
const result = await db
.collection("users")
.doc("user-id")
.update({
// Update personal info
profile: _.set({
nickname: "new nickname",
updatedAt: new Date(),
}),
// Add points
points: _.inc(100),
// Add a new tag (non-repetitive)
tags: _.addToSet("VIP"),
// Delete temporary field
tempToken: _.remove(),
loginCount: _.inc(1),
loginCount: _.inc(1),
});
console.log("Update successful");
Transaction Operations
Support atomic operations on multiple documents to underwrite data consistency.
-Support only server-side use, not supported on the client.
- Please use the Node.js adapter for use in Node.js
startTransaction
async db.startTransaction(): Promise<Transaction>
Start a new transaction.
参数
无参数
返回
Transaction object, perform document operations in a transaction
示例
// Start a transaction.
const transaction = await db.startTransaction();
try {
// Operate document in transaction
const doc = transaction.collection("accounts").doc("account-1");
const accountData = await doc.get();
if (accountData.data && accountData.data.balance >= 100) {
// Deducting funds
await doc.update({
balance: accountData.data.balance - 100,
});
// Add balance to another account
await transaction
.collection("accounts")
.doc("account-2")
.update({
balance: db.command.inc(100),
});
// Commit transactions.
await transaction.commit();
console.log("Fund transfer successful");
} else {
// Roll back transaction
await transaction.rollback("INSUFFICIENT_BALANCE");
}
} catch (error) {
// Roll back when an error occurs
await transaction.rollback(error);
console.error("Transaction failure:", error);
}
runTransaction
async db.runTransaction(callback: (transaction) => Promise<any>, times?: number): Promise<void>
Execute transaction operations with automatic processing of submission and rollback.
参数
Transactional callback function, perform transaction operations in the function
Retry count for transaction conflicts, defaults to 3
返回
Function return value of the transactional callback function
示例
Use runTransaction to automatically manage transactions
const result = await db.runTransaction(async (transaction) => {
// Obtain account 1
const account1 = await transaction
.collection("accounts")
.doc("account-1")
.get();
Obtains account 2
const account2 = await transaction
.collection("accounts")
.doc("account-2")
.get();
if (account1.data.balance < 100) {
// Roll back via rollback and return custom error
await transaction.rollback({ message: "INSUFFICIENT_BALANCE" });
return;
}
// Deducting funds
await transaction
.collection("accounts")
.doc("account-1")
.update({
balance: account1.data.balance - 100,
});
// Adding funds
await transaction
.collection("accounts")
.doc("account-2")
.update({
balance: account2.data.balance + 100,
});
return { success: true, message: "Fund transfer successful" };
});
console.log(result);
// Create document in transaction
const result = await db.runTransaction(async (transaction) => {
// Create a new document
await transaction.collection("orders").doc("order-123").create({
userId: "user-1",
amount: 100,
status: "pending",
createdAt: new Date(),
});
// Update user order count
await transaction
.collection("users")
.doc("user-1")
.update({
orderCount: db.command.inc(1),
});
return { orderId: "order-123" };
});
Real-time listening
watch
watch(options: WatchOptions): DBRealtimeListener
Listen to real-time changes in documents or query results.
参数
返回
Listener object
示例
Listen to changes in a single document
const listener = db
.collection("todos")
.doc("todo-id-123")
.watch({
onChange: (snapshot) => {
console.log("document changes:", snapshot);
console.log("document data:", snapshot.docs);
console.log("change details:", snapshot.docChanges);
},
onError: (error) => {
console.error("Listen error:", error);
},
});
// Close listener
// listener.close();
// Listen to changes in query results
const listener = db
.collection("todos")
.where({
completed: false,
})
.orderBy("createdAt", "desc")
.limit(10)
.watch({
onChange: (snapshot) => {
console.log("query result changes:", snapshot);
// snapshot.type: 'init' means initialization of data
if (snapshot.type === "init") {
console.log("initial data:", snapshot.docs);
} else {
// Handle addition, deletion, modification, and adjustment
snapshot.docChanges.forEach((change) => {
console.log("change type:", change.dataType); // 'add', 'update', 'remove'
console.log("document changes:", change.doc);
});
}
},
onError: (error) => {
console.error("Listen error:", error);
},
});
// Close listener
// listener.close();
// Snapshot data structure
interface Snapshot {
id: number; // Snapshot ID
type?: "init"; // Snapshot type, 'init' means initialization
docs: Record<string, any>; // current document data
docChanges: Array<{
id: number;
dataType: "init" | "add" | "update" | "remove" | "replace" | "limit";
queueType: "init" | "enqueue" | "dequeue" | "update";
docId: string;
doc: Record<string, any>;
updatedFields?: any; // updated field
removedFields?: any; // removed field
}>;
}
Advanced operation
runCommands
async db.runCommands(params: IRunCommandsReq): Promise<IRunCommandsResult>
Execute MongoDB native commands, support batch operations for multiple commands and transaction operations.
-Only the administrator can call the API -During execution in a transaction, any command failure would cause the entire transaction rollback.
参数
返回
示例
// Execute the find command
const result = await db.runCommands({
commands: [
{
find: "users",
filter: { age: { $gte: 18 } },
projection: { name: 1, email: 1 },
sort: { age: -1 },
limit: 10,
},
],
});
console.log("query result:", result.list);
// result.list[0] contains the queried document
// Execute the insert command
const result = await db.runCommands({
commands: [
{
insert: "users",
documents: [
{ name: "Alice", age: 25 },
{ name: "Bob", age: 30 },
],
},
],
});
console.log("insertion result:", result.list);
// [{ n: 2, ok: 1 }]
// Execute the update command
const result = await db.runCommands({
commands: [
{
update: "users",
updates: [
{
q: { _id: "user-id-123" },
u: { $set: { age: 31 } },
},
],
},
],
});
console.log("update result:", result.list);
// [{ n: 1, nModified: 1, ok: 1 }]
// Execute the delete command
const result = await db.runCommands({
commands: [
{
delete: "users",
deletes: [
{ q: { status: "inactive" }, limit: 0 }, // limit: 0 means delete all match
],
},
],
});
console.log("Deletion result:", result.list);
// Execute the aggregate command
const result = await db.runCommands({
commands: [
{
aggregate: "orders",
pipeline: [
{ $match: { status: "completed" } },
{ $group: { _id: "$userId", total: { $sum: "$amount" } } },
],
cursor: {},
},
],
});
console.log("aggregation result:", result.list);
// Batch execute multiple commands (in a transaction)
const result = await db.runCommands({
commands: [
Command 1: Create an order
{
insert: "orders",
documents: [
{
userId: "user123",
amount: 100,
status: "pending",
},
],
},
Command 2: inventory deduction
{
update: "inventory",
updates: [
{
q: { productId: "prod456" },
u: { $inc: { stock: -1 } },
},
],
},
Command 3: Deduct user points
{
update: "users",
updates: [
{
q: { _id: "user123" },
u: { $inc: { credits: -100 } },
},
],
},
],
transactionId: "txn_abc123", // Optional: Execute in a transaction
});
console.log("batch execution result:", result.list);
// result.list[0] - insertion result
// result.list[1] - inventory update result
// result.list[2] - user update result
// Create an index
const result = await db.runCommands({
commands: [
{
createIndexes: "users",
indexes: [
{
key: { email: 1 },
name: "email_1",
unique: true,
},
],
},
],
});
console.log("index creation result:", result.list);
// Supported command format
// Find command
{
find: "collectionName",
filter: {}, // Query condition, for example: { age: { $gte: 18 }, status: "active" }
projection: {}, // Field projection, for example: { name: 1, email: 1, _id: 0 } (only return name and email, do not return _id)
sort: {}, // Sorting order, for example: { createdAt: -1, name: 1 } (in descending order by creation time, in ascending order by name)
limit: 10, // Limit quantity, for example: 10 (return up to 10 records)
skip: 0 // Skip count, for example: 20 (skip the first 20 records, for pagination)
}
// Insert command
{
insert: "collectionName",
documents: [] // Document array to insert, for example: [{ name: "Alice", age: 25 }, { name: "Bob", age: 30 }]
}
// Update command
{
update: "collectionName",
updates: [{
q: {}, // Query condition, for example: { status: "pending" }
u: {}, // Update content, for example: { $set: { status: "active", updatedAt: new Date() } }
upsert: false, // Whether to upsert, for example: true (create if not found)
multi: false // Whether to batch update, for example: true (update all matched documents)
}]
}
// Delete command
{
delete: "collectionName",
deletes: [{
q: {}, // Query condition, for example: { status: "deleted", lastLogin: { $lt: new Date("2024-01-01") } }
limit: 1 // Number of deletions, for example: 0 (delete all), 1 (delete first)
}]
}
// Aggregate command
{
aggregate: "collectionName",
pipeline: [], // Aggregation pipeline, for example: [{ $match: { status: "completed" } }, { $group: { _id: "$userId", total: { $sum: "$amount" } } }]
cursor: {} // Cursor options, for example: { batchSize: 100 } (return 100 every batch)
}
Other functions
serverDate
db.serverDate(options?: { offset?: number }): ServerDate
Get server time.
参数
返回
Server time object
示例
// Use server time
await db.collection("todos").add({
title: "New Task"
createdAt: db.serverDate(), // Current server time
});
// Use server time with offset
await db.collection("todos").add({
title: "Delayed Task"
scheduledAt: db.serverDate({
offset: 60 * 60 * 1000, // 1 hour later
}),
});
RegExp
db.RegExp({ regexp: string, options?: string }): RegExp
Create a regular expression object for fuzzy query.
参数
返回
regular expression object
示例
// Fuzzy query: heading contains "CloudBase"
const result = await db
.collection("todos")
.where({
title: db.RegExp({
regexp: "CloudBase",
options: "i", // case-insensitive
}),
})
.get();
console.log("query result:", result.data);
Aggregation Operator
Obtain aggregation operators through db.command.aggregate for expression calculation in the aggregation pipeline.
| Category | Operator |
|---|---|
| Arithmetic Operator | abs, add, ceil, divide, exp, floor, ln, log, log10, mod, multiply, pow, sqrt, subtract, trunc |
| Array Operator | arrayElemAt, arrayToObject, concatArrays, filter, in, indexOfArray, isArray, map, range, reduce, reverseArray, size, slice, zip |
| Boolean Operator | and, not, or |
| Comparison Operator | cmp, eq, gt, gte, lt, lte, neq |
| Conditional Operator | cond, ifNull, switch |
| Date Operator | dateFromParts, dateFromString, dayOfMonth, dayOfWeek, dayOfYear, isoDayOfWeek, isoWeek, isoWeekYear, millisecond, minute, month, second, hour, week, year |
| String Operator | concat, dateToString, indexOfBytes, indexOfCP, split, strLenBytes, strLenCP, strcasecmp, substr, substrBytes, substrCP, toLower, toUpper |
| Set Operator | allElementsTrue, anyElementTrue, setDifference, setEquals, setIntersection, setIsSubset, setUnion |
| Object Operator | mergeObjects, objectToArray |
| Grouping Operator | addToSet, avg, first, last, max, min, push, stdDevPop, stdDevSamp, sum |
| Other | literal, let, meta |