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

Next.js+MongoDB开发pages/api接口报collection未定义错误如何解决

问题报错

运行Next.js pages/api路径下的接口时触发报错:Cannot read properties of undefined (reading 'collection')

根因
  • 数据库连接为异步操作,原代码在文件顶层调用connectDB()后未等待连接建立完成,请求进入处理函数时getDB()返回的数据库实例还是undefined,调用collection方法直接报错。
  • 原连接模块未做实例缓存,重复调用会创建多余数据库连接。
  • 数据库查询代码混用回调与async/await写法,会导致返回值异常。
  • 缺少连接、查询环节的错误兜底,异常发生时接口会直接崩溃。
修复方案

1. 重写数据库连接模块

替换utils/connectdb.js的原有代码,改为带连接缓存的Promise风格实现,避免时序问题和重复连接:

require("dotenv").config();
const { MongoClient } = require("mongodb");

let cachedClient = null;
let cachedDb = null;

async function connectDB() {
  // 已存在有效连接时直接返回缓存实例
  if (cachedClient && cachedDb) {
    return { db: cachedDb };
  }

  const connectionUri = process.env.DB;
  if (!connectionUri) {
    throw new Error("未配置数据库连接字符串环境变量DB");
  }

  const client = await MongoClient.connect(connectionUri);
  // 如果连接串未指定库名,需在db()中传入实际业务库名,例如client.db("ecommerce")
  const db = client.db();

  cachedClient = client;
  cachedDb = db;
  return { db };
}

module.exports = { connectDB };

2. 修改API接口逻辑

替换原有接口代码,在请求处理函数内部等待数据库连接完成后再执行查询,统一使用async/await写法,移除多余的回调逻辑:

import { connectDB } from '../../../utils/connectdb'

export default async (req, res) => {
  try {
    // 等待数据库连接完成后再获取实例
    const { db } = await connectDB();
    // 直接await查询结果,不要混用回调写法
    const productList = await db.collection('products').find().toArray();
    res.status(200).json({ products: productList });
  } catch (err) {
    console.error("接口处理异常:", err);
    res.status(500).json({ error: "服务端处理失败" });
  }
}
注意事项
  • 检查MongoDB连接串:如果你的DB环境变量值末尾没有指定数据库名,必须在client.db()方法中传入你实际使用的数据库名称,否则会默认连接到test库,后续查询会出现找不到集合的问题。
  • 不要在API路由文件的顶层执行数据库连接操作,Next.js编译阶段会执行顶层代码,容易引发环境变量未加载、连接时序错乱的问题。
  • 带缓存的连接逻辑可以避免Serverless部署场景下MongoDB连接数被打满的问题。

内容的提问来源于stack exchange,提问作者Noureddine Bachikh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 17:54:18