Node+Express连接MongoDB Atlas遇Mongoose缓冲超时及集合自动创建问题
解决MongooseError: Operation
tours.insertOne() buffering timed out错误 问题原因
你的代码中,异步数据库连接函数start()被调用后,会立刻执行testTour.save()操作,但此时MongoDB连接尚未建立完成。Mongoose会将未完成连接时的数据库操作缓冲起来,超过10秒后就会抛出缓冲超时错误。同时mongoose.connect的回调写法和后续操作的执行顺序逻辑错误,无法保证连接完成后再执行数据操作。
解决方案
1. 调整操作执行顺序
将testTour.save()放到数据库连接成功的代码块内,确保只有当连接建立完成后才执行数据插入操作。
2. 修正mongoose.connect写法
移除mongoose.connect的回调函数,利用await特性等待连接操作完成,避免逻辑分离导致的时序问题。
3. 修正端口赋值逻辑
原代码3000 || process.env.PORT会强制使用3000端口,改为process.env.PORT || 3000,优先读取环境变量中的端口配置。
修改后的完整代码
const mongoose = require('mongoose'); const dotenv = require('dotenv'); const app = require('./app'); dotenv.config({ path: './config.env' }); const DB = process.env.DATABASE.replace( '<PASSWORD>', process.env.DATABASE_PASSWORD ); async function start() { try { // 等待数据库连接完成,移除多余回调 await mongoose.connect(DB); console.log('DB connection successful'); // 连接成功后执行save操作 const doc = await testTour.save(); console.log(doc); } catch (err) { console.log('Error: ', err); } } start(); // 优先使用环境变量端口,不存在则用3000 const port = process.env.PORT || 3000; app.listen(port, () => { console.log(`Listening on port ${port}...`); });
关于集合自动创建的说明
Mongoose默认会在第一次插入文档时自动创建复数形式的集合(比如testTour对应tours集合),这是正常行为。如果需要自定义集合名称,在定义Schema时添加collection属性即可:
const tourSchema = new mongoose.Schema( { // 你的字段定义 name: String, price: Number }, { collection: 'custom_tour_collection' } // 指定集合名称 ); const Tour = mongoose.model('Tour', tourSchema);
内容的提问来源于stack exchange,提问作者Dhairya Srivastava
相关产品推荐
相关产品推荐

