跳转到内容
本站为社区维护的非官方中文翻译,与 Cloudflare, Inc. 无关联。本站不提供账户登录,请勿在任何非官方站点输入您的 Cloudflare 账户信息。官方文档:developers.cloudflare.com

MongoDB

最后更新 查看 MarkdownAgent 设置

MongoDB ↗ 是面向文档的数据库。你可以自行运行 MongoDB、使用 MongoDB Atlas ↗(全托管云服务),或使用任何其他兼容 MongoDB 的主机。

此方法适用于每次请求约 300 ms 连接开销可接受的低流量场景。每次 Worker 调用都会创建到 MongoDB 集群的新 TCP 和 TLS 连接。

设置直接连接

要从 Worker 直接连接到 MongoDB:

  1. 你需要现有的 MongoDB 集群和连接字符串。如果没有,请创建 Atlas 集群 ↗,并从 Atlas 控制台复制连接字符串。

  2. 为 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 兼容性标志。

  3. 安装 MongoDB Node.js 驱动:

    npm i mongodb
  4. 将 MongoDB 连接字符串作为 secret 添加到 Worker:

    npx wrangler secret put MONGODB_URI
    # When prompted, paste your MongoDB connection string
  5. 以下示例展示如何从 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 中可用。

  6. 部署 Worker:

    npx wrangler deploy

此方法适用于对延迟敏感的应用。Workers 无法跨请求复用 I/O 对象,因此连接池在普通 Worker 中不起作用。将 MongoClient 放在 Durable Object 中可在请求之间持久化连接,把预热请求的查询延迟从约 300 ms 降到约 35 ms。

使用 Durable Object 设置连接

使用 Durable Object 连接到 MongoDB:

  1. 你需要现有的 MongoDB 集群和连接字符串。如果没有,请创建 Atlas 集群 ↗,并从 Atlas 控制台复制连接字符串。

  2. 为 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 兼容性标志。

  3. 安装 MongoDB Node.js 驱动:

    npm i mongodb
  4. 将 MongoDB 连接字符串作为 secret 添加到 Worker:

    npx wrangler secret put MONGODB_URI
    # When prompted, paste your MongoDB connection string
  5. 创建一个保存 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 能跨请求复用现有连接。

  6. 更新 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 集群所在区域匹配。

  7. 在 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"]
  8. 部署 Worker:

    npx wrangler deploy

Durable Object 生命周期注意事项

  • Durable Object 在大约 70–140 秒没有传入请求后会被驱逐。下一次请求会再次支付冷启动成本。
  • TCP 连接无法在休眠后存活。
  • 你不能通过 RPC 将 MongoClient、Db 或 Collection 对象传回调用方 Worker。请在 Durable Object 内运行所有数据库逻辑。
  • 单个 Durable Object 实例的软限制大约为每秒 1,000 个请求。

使用 Mongoose

在启用 Node.js 兼容性后,Mongoose ↗ 9 及更高版本可在 Workers 上运行。更早版本会加载浏览器 bundle 而不是 Node.js 入口点,并需要对 package.json 的 exports 映射进行手动补丁。现在已不再需要。

以下示例展示 Mongoose Durable Object:

src/MongoDBConnection.jsjs
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();
	}
}
src/MongoDBConnection.tsts
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();
	}
}

后续步骤

这篇文档对您有帮助吗?