操作场景
Node.js 以其事件驱动和非阻塞 I/O 模型,广泛应用于 Web 后端服务和 Serverless 应用开发。MongoDB 官方 Node.js Driver 提供了基于 Promise 的异步 API,与 Node.js 的异步编程模型天然契合。本文提供使用原生驱动和 Mongoose ORM 框架连接云数据库 MongoDB 的完整示例。
前提条件
已创建云数据库 MongoDB 实例,且实例状态为运行中。
已准备一台与 MongoDB 实例在同一 VPC 内的云服务器 CVM,且已安装 Node.js 18 或以上版本。
注意事项
异步编程:MongoDB Node.js Driver 4.x 及以上版本全面采用 Promise/async-await 模式。如您的代码仍使用回调(Callback)风格,建议迁移至 async/await。
连接复用:
MongoClient 实例内置连接池,应在应用中全局复用,避免每次请求都创建新连接。对于 Express/Koa 等 Web 框架,建议在应用启动时创建连接,并通过中间件或依赖注入共享。错误处理:生产环境中应对数据库操作进行异常捕获,区分网络错误(
MongoNetworkError)和操作错误(MongoServerError),并进行相应处理。方式一:原生 MongoDB Driver
安装驱动
npm install mongodb
Running Environment
Operating System: Ubuntu 24.04.3 LTS / x86_64
Runtime Version: GNU bash, version 5.2.21(1)-release (x86_64-pc-linux-gnu)
连接和 CRUD 操作示例
const { MongoClient } = require("mongodb");// 连接 URI(请替换为您的实际连接信息)const uri = "mongodb://mongouser:thepasswordA1@10.66.187.127:27017/admin";// 副本集连接串(推荐):// const uri = "mongodb://mongouser:thepasswordA1@IP1:27017,IP2:27017,IP3:27017/admin?replicaSet=cmgo-xxxxxxxx_0";// 创建客户端(配置连接池参数)const client = new MongoClient(uri, {maxPoolSize: 50, // 连接池上限minPoolSize: 5, // 连接池下限connectTimeoutMS: 10000, // 连接超时 10 秒socketTimeoutMS: 30000, // 套接字超时 30 秒retryWrites: true, // 启用可重试写入retryReads: true, // 启用可重试读取w: "majority", // 写入关注级别});async function main() {try {// 建立连接await client.connect();console.log("连接成功");// 选择数据库和集合const db = client.db("mydb");const collection = db.collection("users");// ========== 插入文档 ==========const insertResult = await collection.insertOne({username: "jack",age: 31,email: "jack@example.com",createdAt: new Date(),});console.log(`插入文档 ID: ${insertResult.insertedId}`);// 批量插入const insertManyResult = await collection.insertMany([{ username: "alice", age: 28, email: "alice@example.com" },{ username: "bob", age: 35, email: "bob@example.com" },]);console.log(`批量插入 ${insertManyResult.insertedCount} 条文档`);// ========== 查询文档 ==========const user = await collection.findOne({ username: "jack" });console.log("查询单条:", user);// 条件查询(年龄大于 30)const cursor = collection.find({ age: { $gt: 30 } });console.log("年龄大于 30 的用户:");for await (const doc of cursor) {console.log(` - ${doc.username}, 年龄: ${doc.age}`);}// ========== 更新文档 ==========const updateResult = await collection.updateOne({ username: "jack" },{ $set: { age: 32, updatedAt: new Date() } });console.log(`更新 ${updateResult.modifiedCount} 条文档`);// ========== 删除文档 ==========const deleteResult = await collection.deleteMany({username: { $in: ["jack", "alice", "bob"] },});console.log(`删除 ${deleteResult.deletedCount} 条文档`);} catch (error) {console.error("操作失败:", error.message);} finally {await client.close();console.log("连接已关闭");}}main();
运行输出示例:
连接成功插入文档 ID: 6789abcdef1234567890abcd批量插入 2 条文档查询单条: { _id: ObjectId('6789abcdef1234567890abcd'), username: 'jack', age: 31, email: 'jack@example.com', createdAt: 2026-04-17T07:00:00.000Z }年龄大于 30 的用户:- jack, 年龄: 31- bob, 年龄: 35更新 1 条文档删除 3 条文档连接已关闭
方式二:Mongoose ORM
Mongoose 是 Node.js 中主流的 MongoDB ORM 框架,提供 Schema 定义、数据验证、中间件等功能,适合构建结构化的应用程序。
安装 Mongoose
npm install mongoose
Running Environment
Operating System: Ubuntu 24.04.3 LTS / x86_64
Runtime Version: GNU bash, version 5.2.21(1)-release (x86_64-pc-linux-gnu)
连接和操作示例
使用 Mongoose 时,URI 中直接指定业务数据库(如
/mydb),并通过 ?authSource=admin 指定认证库为 admin。const mongoose = require("mongoose");// 连接 URI(请替换为您的实际连接信息)const uri = "mongodb://mongouser:thepasswordA1@10.66.187.127:27017/mydb?authSource=admin";async function main() {try {// 建立连接await mongoose.connect(uri, {maxPoolSize: 50,minPoolSize: 5,connectTimeoutMS: 10000,socketTimeoutMS: 30000,});console.log("Mongoose 连接成功");// 定义 Schemaconst userSchema = new mongoose.Schema({username: { type: String, required: true, unique: true },age: { type: Number, min: 0 },email: { type: String },createdAt: { type: Date, default: Date.now },});// 创建 Modelconst User = mongoose.model("User", userSchema);// 插入文档const user = await User.create({username: "jack",age: 31,email: "jack@example.com",});console.log("插入文档:", user);// 查询文档const found = await User.findOne({ username: "jack" });console.log("查询结果:", found);// 更新文档await User.updateOne({ username: "jack" }, { $set: { age: 32 } });console.log("更新完成");// 删除文档await User.deleteOne({ username: "jack" });console.log("删除完成");} catch (error) {console.error("操作失败:", error.message);} finally {await mongoose.disconnect();console.log("连接已关闭");}}main();
常见问题
连接时提示 "MongoServerError: Authentication failed"
错误信息示例:
MongoServerError: Authentication failed.
请按以下步骤排查:
1. 确认 URI 中指定了认证库
admin。// 正确:URI 路径为 /adminconst uri1 = "mongodb://mongouser:thepasswordA1@10.66.187.127:27017/admin";// 正确:连接业务库时通过 authSource 指定认证库const uri2 = "mongodb://mongouser:thepasswordA1@10.66.187.127:27017/mydb?authSource=admin";// 错误:连接业务库时未指定 authSource,驱动将默认以 mydb 库认证,导致认证失败const uri3 = "mongodb://mongouser:thepasswordA1@10.66.187.127:27017/mydb";
Running Environment
Operating System: Ubuntu 24.04.3 LTS / x86_64
Runtime Version: Node.js v22.13.1
2. 确认密码中的特殊字符已进行 URL 编码:使用
encodeURIComponent() 对密码进行编码。const password = encodeURIComponent("pass@123"); // 输出: pass%40123const uri = `mongodb://mongouser:${password}@10.66.187.127:27017/admin`;
Running Environment
Operating System: Ubuntu 24.04.3 LTS / x86_64
Runtime Version: Node.js v22.13.1
3. 确认用户名和密码正确:登录 MongoDB 控制台,在实例管理页面确认用户信息。如忘记密码,可在控制台重置。
连接时提示 "MongoNetworkTimeoutError" 或 "ECONNREFUSED"
错误信息示例:
MongoNetworkTimeoutError: connection timed out
或:
MongoNetworkError: connect ECONNREFUSED 10.66.187.127:27017
请按以下步骤排查:
1. 确认网络连通性:在 CVM 上执行以下命令,验证网络是否可达:
telnet <MongoDB实例IP> 27017
输出
Connected 表示网络可达,请检查认证配置。输出
Connection timed out 或 Connection refused 表示网络不通,请确认 CVM 与 MongoDB 实例在同一 VPC 内,并检查安全组规则。2. 检查连接超时配置:确认
connectTimeoutMS 配置值合理。const client = new MongoClient(uri, {connectTimeoutMS: 10000, // 连接超时 10 秒socketTimeoutMS: 30000, // 套接字超时 30 秒});
3. 确认副本集名称正确:如使用副本集连接串,请确认
replicaSet 参数与控制台实例详情页中的副本集名称一致。使用 Mongoose 连接时提示 "MongooseServerSelectionError"
错误信息示例:
MongooseServerSelectionError: connect ECONNREFUSED 10.66.187.127:27017
请按以下步骤排查:
1. 确认 URI 格式正确:Mongoose 连接 URI 中需同时指定业务数据库和认证库:
// 正确:指定业务库 /mydb 并通过 authSource 指定认证库await mongoose.connect("mongodb://mongouser:thepasswordA1@10.66.187.127:27017/mydb?authSource=admin");// 错误:缺少 authSource 参数await mongoose.connect("mongodb://mongouser:thepasswordA1@10.66.187.127:27017/mydb");
2. 确认 Mongoose 版本:Mongoose 6.x 及以上版本已移除多个旧版连接参数(如
useNewUrlParser、useUnifiedTopology)。如使用较新版本的 Mongoose,请勿传入这些已废弃的参数:// Mongoose 6.x 及以上(正确,无需额外参数)await mongoose.connect(uri, {maxPoolSize: 50,connectTimeoutMS: 10000,});// Mongoose 5.x(需要以下参数)await mongoose.connect(uri, {useNewUrlParser: true,useUnifiedTopology: true,});