NodeJS连接MongoDB时出现‘collection is not a function’类型错误
问题原因及解决方案
核心问题
- 连接被提前关闭:你的连接代码里
finally块调用了await client.close(),这会在连接成功后立刻关闭MongoDB客户端连接。当后续路由尝试操作数据库时,连接已经断开,导致databaseConnection失去有效数据库实例,所以collection不是可用函数。 - 模块导出时机错误:在
async函数内部赋值module.exports,但模块加载是同步的,当路由文件require这个模块时,可能还没完成数据库连接,拿到的导出值是初始的undefined或空对象。
修复步骤
1. 修改数据库连接文件(示例命名为db.js)
移除finally里的client.close(),保持连接长期打开(Express服务器运行期间需要持续连接数据库),并正确导出数据库实例:
const PRIMARY_SERVER = "mongodb://localhost:27017/"; const { MongoClient } = require("mongodb"); const client = new MongoClient(PRIMARY_SERVER, { useNewUrlParser: true, useUnifiedTopology: true, }); let dbInstance; async function connect() { try { await client.connect(); console.log("Connected to MongoDB"); dbInstance = client.db("mydb"); // 连接成功后再启动服务器,避免路由请求时数据库未就绪 const app = require("../app.js"); app.listen(5050, () => { console.log("Server running on port 5050"); }); } catch (e) { console.error("MongoDB connection failed:", e); process.exit(1); // 连接失败直接退出进程,避免无效服务启动 } } connect(); // 导出获取db实例的方法,确保路由能拿到有效连接 module.exports = () => dbInstance;
2. 修复路由代码
- 改用
await处理MongoDB操作,避免回调嵌套 - 修正响应对象错误(原代码误用
result.status,应为res.status)
const getDb = require('../path/to/db.js'); // 根据你的实际文件路径调整 router.post("/pushbill", async function (req, res) { const db = getDb(); try { // 确保`object`是你要插入的数据,比如从req.body获取 const insertResult = await db.collection("bills").insertOne(req.body); console.log(`Added a new bill with id ${insertResult.insertedId}`); res.status(204).send(); } catch (err) { console.error("Error inserting bill:", err); res.status(400).send("Error inserting bill."); } });
额外说明
- MongoDB驱动的
insertOne支持Promise,结合async/await写法更简洁,也更容易捕获错误 - 不要随意关闭MongoDB客户端连接,除非明确知道服务要停止运行
内容的提问来源于stack exchange,提问作者Patryk Dajos
相关产品推荐
相关产品推荐

