You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js无法读取MongoDB数据及连接池报错问题求助

Node.js + MongoDB 查询文档问题排查

问题描述

我编写了一段Node.js代码,用于显示MongoDB集合中的所有文档,代码如下:

const mongodb = require("mongodb");
const express = require("express");
var app = express();
var mongoClient = mongodb.MongoClient;
var conn = "mongodb://localhost:27017";

mongoClient.connect(conn).then((err, client) => {
  if (err) {
    console.log(err);
  } else {
    console.log("connection established");
    var db = client.db("mydb");
    var collection = db.collection("tutorial");
    collection
      .find()
      .toArray()
      .then((data) => {
        console.log(data);
      });
    client.close();
  }
});
app.listen(3000, () => {
  console.log("Server started");
});

我的mydb数据库中只有一个名为tutorial的集合,该集合仅包含一条文档,预期输出应为:

{
  "_id": {
    "$oid": "637bd20b45dc6d7d03eedb49"
  },
  "name": "Bahy",
  "email": "bahy@gmail.com",
  "password": "1234"
}

但实际运行后输出的是MongoClient对象信息而非预期数据。

更新后的报错

按照相关建议修改代码后,出现如下报错:

Error: 
e:\new Node\node_modules\mongodb\lib\cmap\connection_pool.js:452
                const error = this.closed ? new errors_1.PoolClosedError(this) : new errors_1.PoolClearedError(this);
                                            ^

PoolClosedError [MongoPoolClosedError]: Attempted to check out a connection from closed connection pool
    at ConnectionPool.processWaitQueue (e:\new Node\node_modules\mongodb\lib\cmap\connection_pool.js:452:45)
    at ConnectionPool.close (e:\new Node\node_modules\mongodb\lib\cmap\connection_pool.js:260:14)
    at Server.destroy (e:\new Node\node_modules\mongodb\lib\sdam\server.js:128:21)
    at destroyServer (e:\new Node\node_modules\mongodb\lib\sdam\topology.js:445:12)
    at node:internal/util:361:7
    at new Promise (<anonymous>)
    at destroyServer (node:internal/util:347:12)
    at e:\new Node\node_modules\mongodb\lib\sdam\topology.js:226:56
    at Function.from (<anonymous>)
    at Topology.close (e:\new Node\node_modules\mongodb\lib\sdam\topology.js:225:40) {
  address: 'localhost:27017',
  [Symbol(errorLabels)]: Set(0) {}
}

问题分析与解决

1. 原始问题:Promise参数使用错误

mongoClient.connect()返回的是Promise对象,.then()的回调函数仅接收一个成功结果参数,不存在err参数。你原代码中把client当成了错误对象,实际可用的客户端连接被当成了第二个参数(值为undefined),导致后续数据库操作逻辑完全错误,最终输出了错误的对象信息。

2. 更新后的问题:异步操作未完成就关闭连接

collection.find().toArray()是异步操作,你在调用它之后立刻执行client.close(),会导致数据库连接池在查询请求完成前就被关闭,进而抛出"连接池已关闭"的错误。必须等待异步查询完成后,再执行关闭连接的操作。

修正后的代码

const mongodb = require("mongodb");
const express = require("express");
const app = express();
const mongoClient = mongodb.MongoClient;
const conn = "mongodb://localhost:27017";

// 使用async/await简化异步逻辑处理
async function fetchCollectionData() {
  let client;
  try {
    // 建立数据库连接
    client = await mongoClient.connect(conn);
    console.log("connection established");
    
    // 获取集合并查询所有文档
    const db = client.db("mydb");
    const collection = db.collection("tutorial");
    const data = await collection.find().toArray();
    
    console.log(data);
  } catch (err) {
    // 捕获所有操作错误
    console.error("操作出错:", err);
  } finally {
    // 确保无论操作成功或失败,都关闭连接
    if (client) {
      await client.close();
    }
  }
}

// 执行数据查询
fetchCollectionData();

app.listen(3000, () => {
  console.log("Server started");
});

关键改动说明

  • 改用async/await处理异步逻辑,避免回调嵌套,代码可读性更强。
  • 使用try/catch捕获所有可能的错误(包括连接失败、查询失败等)。
  • 将client.close()放在finally块中,并且等待查询操作完成后再执行,确保异步操作不会因连接提前关闭而中断。
  • 显式声明let client,确保在finally块中能正确访问到客户端连接对象。

内容的提问来源于stack exchange,提问作者Bahy Mohamed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 22:40:24