连接MongoDB数据库
连接MongoDB数据库
MongoDB作为流行的NoSQL数据库,与Node.js生态的Mongoose库搭配使用能极大简化数据操作。通过Mongoose连接MongoDB需要理解连接字符串、连接选项和连接事件等核心概念。
基本连接方式
最简单的连接方式只需要提供MongoDB的URI:
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/mydatabase')
.then(() => console.log('Connected to MongoDB'))
.catch(err => console.error('Connection error:', err));
连接字符串格式通常为mongodb://[username:password@]host1[:port1][,...hostN[:portN]][/[database][?options]]
。当需要认证时:
mongoose.connect('mongodb://user:pass@localhost:27017/mydatabase?authSource=admin');
连接选项配置
Mongoose支持丰富的连接选项:
const options = {
useNewUrlParser: true,
useUnifiedTopology: true,
poolSize: 10, // 连接池大小
connectTimeoutMS: 5000, // 连接超时
socketTimeoutMS: 45000, // socket超时
family: 4, // 强制IPv4
authSource: 'admin',
user: 'myUser',
pass: 'myPassword'
};
mongoose.connect('mongodb://localhost:27017/mydatabase', options);
重要选项说明:
useNewUrlParser
: 使用新的URL解析器useUnifiedTopology
: 使用新的拓扑引擎autoIndex
: 是否自动创建索引(生产环境建议false)
连接池优化
连接池管理对性能至关重要:
const options = {
poolSize: 20, // 默认5
maxPoolSize: 100, // 连接池最大数量
minPoolSize: 10, // 连接池最小数量
serverSelectionTimeoutMS: 5000, // 服务器选择超时
heartbeatFrequencyMS: 10000 // 心跳检测频率
};
监控连接池状态:
mongoose.connection.on('connected', () => {
console.log(`Mongoose default connection pool size: ${mongoose.connection.poolSize}`);
});
多数据库连接
实际项目经常需要连接多个数据库:
const db1 = mongoose.createConnection('mongodb://localhost:27017/db1');
const db2 = mongoose.createConnection('mongodb://localhost:27017/db2');
db1.on('open', () => console.log('DB1 connected'));
db2.on('open', () => console.log('DB2 connected'));
// 使用不同连接创建模型
const User = db1.model('User', userSchema);
const Product = db2.model('Product', productSchema);
连接事件处理
Mongoose连接生命周期事件:
mongoose.connection.on('connecting', () => {
console.log('尝试连接MongoDB...');
});
mongoose.connection.on('connected', () => {
console.log('MongoDB连接成功');
});
mongoose.connection.on('disconnected', () => {
console.log('MongoDB连接断开');
});
mongoose.connection.on('reconnected', () => {
console.log('MongoDB重新连接');
});
mongoose.connection.on('error', (err) => {
console.error('MongoDB连接错误:', err);
});
连接重试策略
网络不稳定时需要自动重连:
const options = {
autoReconnect: true, // 已废弃,新版本默认启用
reconnectTries: Number.MAX_VALUE, // 无限重试
reconnectInterval: 1000 // 重试间隔
};
function connectWithRetry() {
return mongoose.connect(uri, options)
.catch(err => {
console.error('连接失败,5秒后重试:', err.message);
return new Promise(resolve =>
setTimeout(() => connectWithRetry().then(resolve), 5000)
);
});
}
TLS/SSL连接
安全连接配置示例:
const fs = require('fs');
const options = {
ssl: true,
sslValidate: true,
sslCA: fs.readFileSync('./ca.pem'),
sslCert: fs.readFileSync('./client.pem'),
sslKey: fs.readFileSync('./client.key'),
sslPass: 'yourpassphrase'
};
mongoose.connect(uri, options);
连接状态检查
实用工具函数示例:
function checkConnectionState() {
const states = {
0: '断开',
1: '已连接',
2: '连接中',
3: '断开中',
99: '未初始化'
};
return states[mongoose.connection.readyState];
}
// 使用示例
console.log(`当前连接状态: ${checkConnectionState()}`);
连接性能优化
生产环境推荐配置:
const prodOptions = {
autoIndex: false, // 生产环境禁用自动索引
bufferCommands: false, // 禁用缓冲
bufferMaxEntries: 0, // 禁用缓冲条目
useCreateIndex: true, // 使用createIndex()替代ensureIndex()
useFindAndModify: false // 使用原生findOneAndUpdate()
};
连接字符串高级用法
分片集群连接示例:
const shardUri = 'mongodb://mongos1.example.com:27017,mongos2.example.com:27017/dbname?replicaSet=shard-rs';
Atlas云数据库连接:
const atlasUri = 'mongodb+srv://cluster0.mongodb.net/dbname?retryWrites=true&w=majority';
连接调试
启用调试模式查看详细日志:
mongoose.set('debug', true);
// 或自定义调试函数
mongoose.set('debug', (collectionName, method, query, doc) => {
console.log(`${collectionName}.${method}`, JSON.stringify(query), doc);
});
连接关闭
正确关闭连接的方式:
async function gracefulShutdown() {
await mongoose.connection.close();
console.log('MongoDB连接已关闭');
process.exit(0);
}
process.on('SIGINT', gracefulShutdown);
process.on('SIGTERM', gracefulShutdown);
连接中间件
使用插件扩展连接功能:
// 定义插件
function connectionLogger(schema) {
schema.post('init', doc => {
console.log(`文档从MongoDB初始化: ${doc._id}`);
});
}
// 应用到连接
mongoose.plugin(connectionLogger);
连接最佳实践
- 使用环境变量管理连接配置:
require('dotenv').config();
mongoose.connect(process.env.MONGODB_URI, {
useNewUrlParser: true,
useUnifiedTopology: true
});
- 实现健康检查端点:
app.get('/health', (req, res) => {
if (mongoose.connection.readyState === 1) {
res.status(200).json({ status: 'OK' });
} else {
res.status(503).json({ status: 'DB disconnected' });
}
});
- 连接超时处理:
const connectWithTimeout = async () => {
const timeout = setTimeout(() => {
throw new Error('数据库连接超时');
}, 5000);
await mongoose.connect(uri);
clearTimeout(timeout);
};
连接问题排查
常见错误处理:
mongoose.connect(uri).catch(err => {
if (err.name === 'MongoNetworkError') {
console.error('网络问题:', err.message);
} else if (err.name === 'MongooseServerSelectionError') {
console.error('服务器选择失败:', err.message);
} else if (err.name === 'MongoError' && err.code === 18) {
console.error('认证失败:', err.message);
}
});
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:使用npm安装Mongoose
下一篇:连接池配置与优化