MongoDB ↗ 是面向文档的数据库。你可以自行运行 MongoDB、使用 MongoDB Atlas ↗(全托管云服务),或使用任何其他兼容 MongoDB 的主机。
此方法适用于每次请求约 300 ms 连接开销可接受的低流量场景。每次 Worker 调用都会创建到 MongoDB 集群的新 TCP 和 TLS 连接。
要从 Worker 直接连接到 MongoDB:
-
你需要现有的 MongoDB 集群和连接字符串。如果没有,请创建 Atlas 集群 ↗,并从 Atlas 控制台复制连接字符串。
-
为 Worker 启用 Node.js 兼容性:
对于
2026-08-04或更晚的兼容性日期,Workers 和 Pages 项目默认启用nodejs_compat和nodejs_compat_v2。内置运行时 API 和 polyfill 无需额外配置即可使用。这些兼容性日期不使用这两个标志。现有项目更新兼容性日期时,无需移除这些标志。如果兼容性日期早于
2026-08-04,请将nodejs_compat兼容性标志添加到 Wrangler 配置文件中以启用:{ "compatibility_flags": [ "nodejs_compat" ] }compatibility_flags = [ "nodejs_compat" ]要针对
2026-08-04或更晚的兼容性日期完全关闭 Node.js 兼容性,请先移除已有的启用标志,然后同时添加no_nodejs_compat和no_nodejs_compat_v2。配置示例请参阅 Node.js 兼容性标志。 -
安装 MongoDB Node.js 驱动:
npm i mongodbyarn add mongodbpnpm add mongodbbun add mongodb -
将 MongoDB 连接字符串作为 secret 添加到 Worker:
npx wrangler secret put MONGODB_URI # When prompted, paste your MongoDB connection string -
以下示例展示如何从 Worker 查询 MongoDB 数据库:
src/index.jsjs import { MongoClient } from "mongodb"; export default { async fetch(request, env, ctx) { const client = new MongoClient(env.MONGODB_URI); await client.connect(); const movie = await client .db("sample_mflix") .collection("movies") .findOne( { title: "The Room" }, { projection: { _id: 0, title: 1, imdb: 1 } }, ); return Response.json({ movie }); }, };src/index.tsts import { MongoClient } from "mongodb"; export interface Env { MONGODB_URI: string; } export default { async fetch(request, env, ctx): Promise<Response> { const client = new MongoClient(env.MONGODB_URI); await client.connect(); const movie = await client .db("sample_mflix") .collection("movies") .findOne( { title: "The Room" }, { projection: { _id: 0, title: 1, imdb: 1 } }, ); return Response.json({ movie }); }, } satisfies ExportedHandler<Env>;MongoDB 驱动使用
node:net和node:tls模块。在启用nodejs_compat且兼容性日期为2025-03-20或更晚时,这些模块在 Workers 中可用。 -
部署 Worker:
npx wrangler deploy
此方法适用于对延迟敏感的应用。Workers 无法跨请求复用 I/O 对象,因此连接池在普通 Worker 中不起作用。将 MongoClient 放在 Durable Object 中可在请求之间持久化连接,把预热请求的查询延迟从约 300 ms 降到约 35 ms。
使用 Durable Object 连接到 MongoDB:
-
你需要现有的 MongoDB 集群和连接字符串。如果没有,请创建 Atlas 集群 ↗,并从 Atlas 控制台复制连接字符串。
-
为 Worker 启用 Node.js 兼容性:
对于
2026-08-04或更晚的兼容性日期,Workers 和 Pages 项目默认启用nodejs_compat和nodejs_compat_v2。内置运行时 API 和 polyfill 无需额外配置即可使用。这些兼容性日期不使用这两个标志。现有项目更新兼容性日期时,无需移除这些标志。如果兼容性日期早于
2026-08-04,请将nodejs_compat兼容性标志添加到 Wrangler 配置文件中以启用:{ "compatibility_flags": [ "nodejs_compat" ] }compatibility_flags = [ "nodejs_compat" ]要针对
2026-08-04或更晚的兼容性日期完全关闭 Node.js 兼容性,请先移除已有的启用标志,然后同时添加no_nodejs_compat和no_nodejs_compat_v2。配置示例请参阅 Node.js 兼容性标志。 -
安装 MongoDB Node.js 驱动:
npm i mongodbyarn add mongodbpnpm add mongodbbun add mongodb -
将 MongoDB 连接字符串作为 secret 添加到 Worker:
npx wrangler secret put MONGODB_URI # When prompted, paste your MongoDB connection string -
创建一个保存
MongoClient实例的 Durable Object 类:src/MongoDBConnection.jsjs import { DurableObject, DurableObjectState } from "cloudflare:workers"; import { MongoClient } from "mongodb"; export class MongoDBConnection extends DurableObject { client; constructor(state, env) { super(state, env); this.client = new MongoClient(env.MONGODB_URI, { maxPoolSize: 1, minPoolSize: 0, serverSelectionTimeoutMS: 5000, maxIdleTimeMS: 20_000, }); } async getMovie() { const start = Date.now(); await this.client.connect(); const movie = await this.client .db("sample_mflix") .collection("movies") .findOne( { title: "The Room" }, { projection: { _id: 0, title: 1, imdb: 1 } }, ); return { movie, queryTime: Date.now() - start }; } }src/MongoDBConnection.tsts import { DurableObject, DurableObjectState } from "cloudflare:workers"; import { MongoClient } from "mongodb"; interface Env { MONGODB_URI: string; } export class MongoDBConnection extends DurableObject { private client: MongoClient; constructor(state: DurableObjectState, env: Env) { super(state, env); this.client = new MongoClient(env.MONGODB_URI, { maxPoolSize: 1, minPoolSize: 0, serverSelectionTimeoutMS: 5000, maxIdleTimeMS: 20_000, }); } async getMovie() { const start = Date.now(); await this.client.connect(); const movie = await this.client .db("sample_mflix") .collection("movies") .findOne( { title: "The Room" }, { projection: { _id: 0, title: 1, imdb: 1 } }, ); return { movie, queryTime: Date.now() - start }; } }在构造函数中创建
MongoClient,并在请求处理程序中调用connect(),使 Durable Object 能跨请求复用现有连接。 -
更新 Worker 入口点,将请求路由到 Durable Object:
src/index.tsts import { MongoDBConnection } from "./MongoDBConnection"; interface Env { MONGODB_URI: string; MONGODB_CONNECTION: DurableObjectNamespace<MongoDBConnection>; } export default { async fetch(request: Request, env: Env): Promise<Response> { const id = env.MONGODB_CONNECTION.idFromName("mongodb-connection"); const stub = env.MONGODB_CONNECTION.get(id, { locationHint: "enam" }); const result = await stub.getMovie(); return Response.json(result); }, } satisfies ExportedHandler<Env>; export { MongoDBConnection };使用
locationHint选项将 Durable Object 放在靠近 MongoDB 集群的位置。可用提示包括wnam、enam、sam、weur、eeur、apac、oc、afr和me。将提示与 MongoDB 集群所在区域匹配。 -
在 Wrangler 文件中配置 Durable Object 绑定和迁移:
{ "$schema": "./node_modules/wrangler/config-schema.json", "name": "workers-mongodb-demo", "main": "src/index.ts", // Set this to today's date "compatibility_date": "2026-11-14", "compatibility_flags": [ "nodejs_compat" ], "durable_objects": { "bindings": [ { "name": "MONGODB_CONNECTION", "class_name": "MongoDBConnection" } ] }, "migrations": [ { "tag": "v1", "new_classes": [ "MongoDBConnection" ] } ] }name = "workers-mongodb-demo" main = "src/index.ts" # Set this to today's date compatibility_date = "2026-11-14" compatibility_flags = ["nodejs_compat"] [[durable_objects.bindings]] name = "MONGODB_CONNECTION" class_name = "MongoDBConnection" [[migrations]] tag = "v1" new_classes = ["MongoDBConnection"] -
部署 Worker:
npx wrangler deploy
- Durable Object 在大约 70–140 秒没有传入请求后会被驱逐。下一次请求会再次支付冷启动成本。
- TCP 连接无法在休眠后存活。
- 你不能通过 RPC 将
MongoClient、Db或Collection对象传回调用方 Worker。请在 Durable Object 内运行所有数据库逻辑。 - 单个 Durable Object 实例的软限制大约为每秒 1,000 个请求。
在启用 Node.js 兼容性后,Mongoose ↗ 9 及更高版本可在 Workers 上运行。更早版本会加载浏览器 bundle 而不是 Node.js 入口点,并需要对 package.json 的 exports 映射进行手动补丁。现在已不再需要。
以下示例展示 Mongoose Durable Object:
import { DurableObject } from "cloudflare:workers";
import mongoose, { Schema, Model } from "mongoose";
const movieSchema = new Schema({
title: String,
imdb: { rating: Number, votes: Number, id: Number },
});
export class MongoDBConnection extends DurableObject {
Movie;
constructor(state, env) {
super(state, env);
this.Movie = mongoose.model("Movie", movieSchema, "movies");
}
async getMovie() {
if (mongoose.connection.readyState === 0) {
await mongoose.connect(this.env.MONGODB_URI, { dbName: "sample_mflix" });
}
return this.Movie.findOne(
{ title: "The Room" },
{ _id: 0, title: 1, imdb: 1 },
).lean();
}
}import { DurableObject } from "cloudflare:workers";
import mongoose, { Schema, Model } from "mongoose";
interface Env {
MONGODB_URI: string;
}
const movieSchema = new Schema({
title: String,
imdb: { rating: Number, votes: Number, id: Number },
});
export class MongoDBConnection extends DurableObject<Env> {
private Movie: Model<any>;
constructor(state: DurableObjectState, env: Env) {
super(state, env);
this.Movie = mongoose.model("Movie", movieSchema, "movies");
}
async getMovie() {
if (mongoose.connection.readyState === 0) {
await mongoose.connect(this.env.MONGODB_URI, { dbName: "sample_mflix" });
}
return this.Movie.findOne(
{ title: "The Room" },
{ _id: 0, title: 1, imdb: 1 },
).lean();
}
}- 了解更多关于 Durable Objects 的信息。
- 查阅 MongoDB Node.js 驱动文档 ↗。
- 探索 Workers 的其他存储选项。