MERN开发中Mongoose向MongoDB插数据遇超时及连接拒绝问题
我是MERN开发新手,尝试通过Mongoose将用户的用户名、邮箱和密码插入MongoDB时出现异常。使用VSCode的Thunder Client以JSON格式调用接口添加用户时,先触发users.insertOne()缓冲超时错误导致应用崩溃;后续将代码修改为async/await形式后,又出现MongooseServerSelectionError: connect ECONNREFUSED错误。
已通过sudo systemctl start mongodb启动MongoDB服务,服务状态显示正常,但数据库连接及数据插入仍失败。相关错误日志、代码及服务状态如下:
初始错误日志
[nodemon] 2.0.19 [nodemon] to restart at any time, enter `rs` [nodemon] watching path(s): *.* [nodemon] watching extensions: js,mjs,json [nodemon] starting `node ./index.js` Example app listening on port 3000 connected to mongodb successfully { name: 'kashish', email: 'mail@mail.com', password: '1234' } /home/alien/codes/webDev/react/inotebook/backend/node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js:151 const err = new MongooseError(message); ^ MongooseError: Operation `users.insertOne()` buffering timed out after 10000ms at Timeout.<anonymous> (/home/alien/codes/webDev/react/inotebook/backend/node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js:151:23) at listOnTimeout (node:internal/timers:564:17) at process.processTimers (node:internal/timers:507:7) Node.js v18.7.0
[nodemon] app crashed - waiting for file changes before starting...
修改代码后的错误日志
Example app listening on port 3000 error MongooseServerSelectionError: connect ECONNREFUSED ::1:27017 at Connection.openUri (/home/alien/codes/webDev/react/inotebook/backend/node_modules/mongoose/lib/connection.js:824:32) at /home/alien/codes/webDev/react/inotebook/backend/node_modules/mongoose/lib/index.js:380:10 at /home/alien/codes/webDev/react/inotebook/backend/node_modules/mongoose/lib/helpers/promiseOrCallback.js:41:5 at new Promise (<anonymous>) at promiseOrCallback (/home/alien/codes/webDev/react/inotebook/backend/node_modules/mongoose/lib/helpers/promiseOrCallback.js:40:10) at Mongoose._promiseOrCallback (/home/alien/codes/webDev/react/inotebook/backend/node_modules/mongoose/lib/index.js:1225:10) at Mongoose.connect (/home/alien/codes/webDev/react/inotebook/backend/node_modules/mongoose/lib/index.js:379:20) at connectMongo (/home/alien/codes/webDev/react/inotebook/backend/db.js:5:14) at Object.<anonymous> (/home/alien/codes/webDev/react/inotebook/backend/index.js:3:1) at Module._compile (node:internal/modules/cjs/loader:1120:14) { reason: TopologyDescription { type: 'Unknown', servers: Map(1) { 'localhost:27017' => [ServerDescription] }, stale: false, compatible: true, heartbeatFrequencyMS: 10000, localThresholdMS: 15, logicalSessionTimeoutMinutes: undefined }, code: undefined }
MongoDB服务状态
● mongodb.service - MongoDB Database Server Loaded: loaded (/usr/lib/systemd/system/mongodb.service; disabled; preset: disabled) Active: active (running) since Mon 2022-08-22 14:59:01 IST; 24s ago Docs: https://docs.mongodb.org/manual Main PID: 5840 (mongod) Memory: 163.0M CPU: 857ms CGroup: /system.slice/mongodb.service └─5840 /usr/bin/mongod --config /etc/mongodb.conf
相关代码
数据库连接代码
const mongoose=require("mongoose") const mongoUri="mongodb://localhost:27017" const connectMongo=() => { mongoose.connect(mongoUri).then( () => console.log('connected') ).catch(e => console.log('error',e)) } module.exports=connectMongo;
用户插入接口代码
const express=require('express'); const User=require('../models/User'); const router=express.Router(); router.get('/',async (req,res) => { console.log(req.body); const user=User(req.body); await user.save() res.send(req.body); }) module.exports=router;
问题分析与解决
1. 数据库连接失败(ECONNREFUSED)
错误connect ECONNREFUSED ::1:27017表明Mongoose尝试通过IPv6的::1地址连接MongoDB,但你的MongoDB可能仅监听IPv4的127.0.0.1地址。
修复步骤:
- 修改连接字符串为明确的IPv4地址,并指定目标数据库名(避免默认连接
test库):const mongoUri="mongodb://127.0.0.1:27017/inotebook" - 检查MongoDB配置文件
/etc/mongodb.conf中的bindIp配置,确保设置为127.0.0.1或0.0.0.0(允许本地连接)。修改后重启服务:sudo systemctl restart mongodb
2. 缓冲超时错误根源
初始的users.insertOne()缓冲超时错误本质是数据库连接未真正建立,Mongoose缓冲操作超时后抛出异常。解决连接问题后,该错误会自动消失。
3. 接口请求方法错误
你用GET接口处理用户创建,但GET请求通常不携带请求体,Thunder Client发送的JSON数据无法被Express解析到req.body,导致插入数据为空。
修复步骤:
- 将接口改为POST方法(创建资源的标准HTTP方法),并添加错误捕获:
router.post('/', async (req, res) => { try { console.log(req.body); const user = new User(req.body); // 使用new关键字实例化模型 await user.save(); res.status(201).json(user); // 返回创建后的用户数据 } catch (err) { res.status(400).json({ error: err.message }); // 返回错误信息给客户端 } }) - 在Express主文件(
index.js)中添加JSON解析中间件,否则req.body会是undefined:app.use(express.json());
4. 模型实例化错误
原代码中const user=User(req.body);缺少new关键字,无法正确创建Mongoose文档实例,导致save()调用失败。必须用new User(req.body)来实例化模型。
内容的提问来源于stack exchange,提问作者kashish patel

