MongoDB MongooseError:在初始连接完成之前无法调用`collection.aggregate()`

Jul*_*ius 2 mongoose mongodb node.js next.js

我的网站使用NextJS构建(并使用 Vercel 托管),在 NodeJS API 中使用 Mongoose 连接到我的 MongoDB 数据库。

我只有大约 1% 的用户遇到这个奇怪的错误:

MongooseError: Cannot call `hotels.aggregate()` before initial connection is complete if `bufferCommands = false`. Make sure you `await mongoose.connect()` if you have `bufferCommands = false`.
at NativeCollection.<computed> [as aggregate] (/var/task/node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js:193:15)
at /var/task/node_modules/mongoose/lib/aggregate.js:998:18
at /var/task/node_modules/kareem/index.js:23:7
at processTicksAndRejections (internal/process/task_queues.js:77:11)
Run Code Online (Sandbox Code Playgroud)

hotels是正在显示的集合,我.aggregate()在 API 中调用它的函数)

我无法可靠地重现该错误,但我也遇到过这种情况。

我按照 NextJS 推荐的方式从他们的示例连接到 MonogoDB :

import mongoose from 'mongoose'

const MONGODB_URI = process.env.MONGODB_URI

if (!MONGODB_URI) {
  throw new Error(
    'Please define the MONGODB_URI environment variable inside .env.local'
  )
}

/**
 * Global is used here to maintain a cached connection across hot reloads
 * in development. This prevents connections growing exponentially
 * during API Route usage.
 */
let cached = global.mongoose

if (!cached) {
  cached = global.mongoose = { conn: null, promise: null }
}

async function dbConnect() {
  if (cached.conn) {
    return cached.conn
  }

  if (!cached.promise) {
    const opts = {
      bufferCommands: false,
    }

    cached.promise = mongoose.connect(MONGODB_URI, opts).then((mongoose) => {
      return mongoose
    })
  }
  cached.conn = await cached.promise
  return cached.conn
}

export default dbConnect
Run Code Online (Sandbox Code Playgroud)

与错误消息相反,我正在等待 mongoose.connect()。我的 API 是这样开始的:

import dbConnect from "utils/dbConnect";
import HotelModel from "models/HotelModel";

export default async function handler(req, res) {
  await dbConnect();

      try {
        const pipeline = {}; // this is a big aggregation pipeline

        const hotels = await HotelModel.aggregate(pipeline);

        return res.status(200).json(hotels);
      } catch{
        ... 
      }
}
Run Code Online (Sandbox Code Playgroud)

有谁知道为什么会发生这种情况?

Ale*_*lex 8

消除

const opts = {
      bufferCommands: false,
}
Run Code Online (Sandbox Code Playgroud)

bufferCommands: true明确设置。

Vercel 在 AWS Lambda 上运行,有时会导致缓存连接出现问题。Vercel 贡献者之一抱怨 mongoose 中的相应 PR https://github.com/Automattic/mongoose/issues/9239#issuecomment-659000910

他们建议避免bufferCommands: false在线程中使用,并在一年后将其从官方猫鼬建议中删除:docs/lambda.md