Mongoose查询超时问题:访问不存在的MongoDB Atlas数据库报错
问题:MongoDB Atlas查询不存在的数据库时触发超时,而非返回预期的null
尝试从MongoDB Atlas中一个不存在的数据库获取数据,原本预期返回null,却出现超时错误:MongooseError: Operation \birthdays.findOne()` buffering timed out after 10000ms。已确认连接日志显示数据库连接成功,疑惑该超时是否因目标数据库不存在导致,同时想了解在调用find/exists`方法前无预定义集合时的解决办法。
相关代码
connect-db.js
import { connect } from "mongoose"; import "dotenv/config"; const connectDb = async () => { try { const conn = await connect(`${process.env.MONGO_URI}/discord`); console.log(`Mongo db connected: ${conn.connection.host}`); } catch (error) { console.log(error); process.exit(1); } }; connectDb();
Schema与Model文件
import { model, Schema } from "mongoose"; const BirthdaySchema = new Schema({ discordID: String, birth_date: String, }); const BirthdayModel = model("birthday", BirthdaySchema); export default BirthdayModel;
get_birthday.js
import BirthdayModel from "../models/birthday_model.js"; export const getBirthday = async (id) => { try { const getData = await BirthdayModel.exists({ discordID: id }); if (!getData) { return null; } console.log(getData); return getData; } catch (error) { throw new Error(error); } };
完整错误信息
Error: MongooseError: Operation `birthdays.findOne()` buffering timed out after 10000ms at getBirthday (file:///home/xxxx/Documents/xxxx/modules/get_birthday.js:12:15) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async Object.execute (file:///home/xxxx/Documents/xxxx/commands/set_birthday.js:26:25) at async Object.execute (file:///home/xxxx/Documents/xxxx/events/interaction.js:17:13) node:events:492 throw er; // Unhandled 'error' event
原因与解决办法
原因分析
超时错误并非直接由数据库不存在导致,而是Mongoose的操作缓冲机制在连接未完全就绪时执行查询,最终触发缓冲超时。即使日志显示连接成功,实际连接可能仍处于初始化阶段;同时MongoDB自动创建不存在的数据库/集合需要时间,进一步拉长了缓冲等待时间,最终超过默认10秒阈值抛出错误。
解决步骤
确保连接完全就绪后再执行查询
修改connect-db.js导出连接函数,在应用入口等待连接完成后再加载业务逻辑:// connect-db.js 修改后 import { connect } from "mongoose"; import "dotenv/config"; export const connectDb = async () => { try { const conn = await connect(`${process.env.MONGO_URI}/discord`); console.log(`Mongo db connected: ${conn.connection.host}`); return conn; } catch (error) { console.log(error); process.exit(1); } };在应用入口文件(如
index.js)中等待连接就绪:import { connectDb } from "./connect-db.js"; import { getBirthday } from "./modules/get_birthday.js"; async function startApp() { await connectDb(); // 连接就绪后再执行查询或加载其他业务模块 const result = await getBirthday("123456"); console.log(result); } startApp();禁用Mongoose操作缓冲(可选)
在连接选项中设置bufferCommands: false,让连接未就绪时的查询直接抛出错误,避免长时间缓冲等待:const conn = await connect(`${process.env.MONGO_URI}/discord`, { bufferCommands: false });注意:禁用缓冲后需自行保证查询仅在连接就绪后执行,否则会立即抛出错误。
预检查数据库/集合是否存在
若需要提前确认目标数据库或集合是否存在,可在查询前执行检查:// 检查数据库是否存在 const checkDbExists = async () => { const dbs = await mongoose.connection.client.db().admin().listDatabases(); return dbs.databases.some(db => db.name === "discord"); }; // 检查集合是否存在 const checkCollectionExists = async () => { const collections = await mongoose.connection.db.listCollections({ name: "birthdays" }).toArray(); return collections.length > 0; };可在
getBirthday函数开头加入这些检查,按需返回null或执行后续查询。
内容的提问来源于stack exchange,提问作者Harsha Vardhan
相关产品推荐
相关产品推荐

