Connections
你可以使用 mongoose.connect() 方法连接 MongoDB 。
mongoose.connect('mongodb://localhost/myapp');
这是连接到本地 myapp 数据库默认接口(27017)的最小配置。
本地连接失败可以尝试连接 127.0.0.1 。
local hostname 被修改有时候会引起问题。
你也可以在 uri 中指定多个参数:
mongoose.connect('mongodb://username:password@host:port/database?options...');
详情请看 mongodb connection string spec for more detail.
操作缓存
你不必等待连接建立成功就可以使用你的 Mongoose models 。
mongoose.connect('mongodb://localhost/myapp');
var MyModel = mongoose.model('Test', new Schema({ name: String }));
// 可行
MyModel.findOne(function(error, result) { /* ... */ });
Mongoose 会缓存你的 model 操作。这个操作很方便,但也回引起一些疑惑, 因为如果你没连上 ,Mongoose 不会 抛错。
var MyModel = mongoose.model('Test', new Schema({ name: String }));
// 连接成功前操作会被挂起
MyModel.findOne(function(error, result) { /* ... */ });
setTimeout(function() {
mongoose.connect('mongodb://localhost/myapp');
}, 60000);
要禁用缓存,请修改 bufferCommands 配置。
如果你打开了 bufferCommands 连接被挂起,尝试关闭 bufferCommands
检查你是否正确打开连接。
你也可以全局禁用 bufferCommands :
mongoose.set('bufferCommands', false);
选项
connect 方法也接受 options 参数,这些参数会传入底层 MongoDB 驱动。
mongoose.connect(uri, options);
完整参数列表请参考
MongoDB Node.js 驱动文档
connect()。
Mongoose 会不做修改直接把选项传到驱动,以下有一点例外
bufferCommands- 这是 mongoose 特有的选项 (不传到 MongoDB) ,禁用 mongoose 缓存机制user/pass- 用于认证的用户名和密码。mongoose 特有,等价于 MongoDB 驱动的auth.user和auth.password选项autoIndex- 默认情况下,mongoose 在连接时会自动建立 schema 的索引。这有利于开发,但是在大型生产环境下不是十分理想,因为索引建立会导致性能下降。如果autoIndex设为 false,mongoose 将不会自动建立索引dbName- 指定要连接的数据库名称(覆盖连接字符串)。 如果你使用mongodb+srv语法连接 MongoDB Atlas, 你 需要使用dbName指定数据库
以下是一些重要选项
autoReconnect- 底层 MongoDB 驱动在连接丢失后将自动重连。除非你是可以自己管理连接池的高手,否则不要把这个选项设为falsereconnectTries- If you're connected to a single server or mongos proxy (as opposed to a replica set), the MongoDB driver will try to reconnect everyreconnectIntervalmilliseconds forreconnectTriestimes, and give up afterward. When the driver gives up, the mongoose connection emits areconnectFailedevent. This option does nothing for replica set connections.reconnectInterval- 见reconnectTriespromiseLibrary- 设定底层 promise 库poolSize- MongoDB 保持的最大 socket 连接数。poolSize的默认值是 5。注意,MongoDB 3.4 之前, MongoDB 只允许每个 socket 同时进行一个操作,所以如果你有几个缓慢请求卡着后面快的请求,可以尝试增加连接数。bufferMaxEntries- MongoDB 驱动同样有自己的离线时缓存机制。如果你希望链接错误时终止数据库操作,请将此选项设为 0 以及把bufferCommands设为false。
举例:
const options = {
useMongoClient: true,
autoIndex: false, // Don't build indexes
reconnectTries: Number.MAX_VALUE, // Never stop trying to reconnect
reconnectInterval: 500, // Reconnect every 500ms
poolSize: 10, // Maintain up to 10 socket connections
// If not connected, return errors immediately rather than waiting for reconnect
bufferMaxEntries: 0
};
mongoose.connect(uri, options);
回调
connect() 函数接受回调函数,或返回一个 promise。
mongoose.connect(uri, options, function(error) {
// Check error in initial connection. There is no 2nd param to the callback.
});
// Or using promises
mongoose.connect(uri, options).then(
() => { /** ready to use. The `mongoose.connect()` promise resolves to undefined. */ },
err => { /** handle initial connection error */ }
);
连接字符串( Connection String )选项
你也可以在连接字符串填写驱动选项,但是这只适用于 MongoDB 驱动使用的选项,
所以类似 bufferCommands 的 Mongoose 专用选项不能在连接字符串使用。
mongoose.connect('mongodb://localhost:27017/test?connectTimeoutMS=1000&bufferCommands=false');
// The above is equivalent to:
mongoose.connect('mongodb://localhost:27017/test', {
connectTimeoutMS: 1000
// Note that mongoose will **not** pull `bufferCommands` from the query string
});
把选项放在连接字符串的劣势是不便于阅读,优势是你只需要写一条连接而不需要把所有设定分开写。
最佳实践是把区分生产环境和开发环境的选项如 socketTimeoutMS 、 connectTimeoutMS 放在 uri ,
把通用的常量如 connectTimeoutMS 、 poolSize 放在选项对象里。
MongoDB 的文档可以找到关于连接字符串的所有选项。
keepAlive 注意事项
对于长期运行的后台应用,启用毫秒级 keepAlive 是一个精明的操作。不这么做你可能会经常
收到看似毫无原因的 "connection closed" 错误。遇到这个情况,
阅读这篇文章,
你或许会立刻启用 keepAlive:
mongoose.connect(uri, { keepAlive: 120 });
副本集(Replica Set)连接
要连接到副本集,你可以用逗号分隔,传入多个地址。
mongoose.connect('mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]' [, options]);
连接到单节点副本集,需指定 replicaSet 选项。
mongoose.connect('mongodb://host1:port1/?replicaSet=rsName');
多 mongos 支持
使用高性能分片集群,需要连接多个 mongos(MongoDB Shard) 实例。 在 mongoose 5.x 中, 你在连接多个 mongos 时不需要传入任何特殊选项。
// Connect to 2 mongos servers
mongoose.connect('mongodb://mongosA:27501,mongosB:27501', cb);
多个连接
之前我们了解如何使用 Mongoose 默认连接方法连接到 MongoDB。但有时候我们需要权限不同的多个连接,
或是连接到不同数据库。这个情况下我们可以使用 mongoose.createConnection(),
它接受之前提到的所有参数,给你返回一个新的连接。
const conn = mongoose.createConnection('mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]', options);
connection 对象后续用于创建和检索 models。 models 的范围总是局限于单个连接。
调用 mongoose.connect() 时,Mongoose 会自动创建默认连接。
你可以使用 mongoose.connection 访问默认连接。
连接池
无论是使用 mongoose.connect 或是 mongoose.createConnection 创建的连接,
都被纳入默认最大为 5 的连接池,可以通过 poolSize 选项调整:
// With object options
mongoose.createConnection(uri, { poolSize: 4 });
const uri = 'mongodb://localhost/test?poolSize=4';
mongoose.createConnection(uri);
v5.x 的变化
从 4.x 升级到 5.x,你可能会看到一下弃用提示,
你不应该在 4.x 使用 useMongoClient 选项:
the server/replset/mongos options are deprecated, all their options are supported at the top level of the options object
旧版的 MongoDB 驱动中你需要为多连接配置特定选项:
mongoose.connect(myUri, {
server: {
socketOptions: {
socketTimeoutMS: 0,
keepAlive: true
},
reconnectTries: 30
},
replset: {
socketOptions: {
socketTimeoutMS: 0,
keepAlive: true
},
reconnectTries: 30
},
mongos: {
socketOptions: {
socketTimeoutMS: 0,
keepAlive: true
},
reconnectTries: 30
}
});
mongoose v5.x 中,你可以把所有选项写在顶层而不用嵌套到每个属性。 点击这里查看所有选项列表。
// Equivalent to the above code
mongoose.connect(myUri, {
socketTimeoutMS: 0,
keepAlive: true,
reconnectTries: 30
});
下一步
现在我们介绍了 mongoose 的连接方式,接着看看 models。
