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

Next.js 14中间件中Mongoose模型调用报错:find不是函数

Next.js中间件中调用Mongoose模型报错:User.find is not a function

问题重现

在Next.js 14.1中间件中执行以下代码查询用户:

let user: UserType[] | null = null;

try {
    user = await findUser({id});
    console.log("user", user);
} catch (error: any) {
    throw new Error(error)
}

出现如下错误:

⨯ unhandledRejection: Error: TypeError: ___WEBPACK_IMPORTED_MODULE_0__.User.find is not a function
at addSiteToIntegration (webpack-internal:///(middleware)/./middleware.ts:51:15)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

对应的Mongoose User Schema如下:

import mongoose from "mongoose";

const UserSchema = new mongoose.Schema({
    userId: String,
    name: {
        type: String,
        required: true,
    },
    email: String,
    phone: String,
    city: {
        type: String,
        default: "",
    },
    apiKeys: [
        {
            purpose: String,
            key: String,
            allowedOrigins: Array,
        },
    ],
    customerRating: {
        type: Number,
        required: true,
        default: 0,
    },
    businessName: String,
    businessRating: Number,
    bio: String,
    businessBio: String,
    businessDisplayName: String,
    isBetaUser: {
        type: Boolean,
        default: false,
    },
    reviewWizardPresets: [
        {
            id: String,
            text: String,
            onStars: String,
        },
    ],
    blockList: [
        {
            type: String,
        },
    ],
    accesingWebsites: [{ url: String, description: String, name: String }],
    createdAt: {
        type: Date,
        required: true,
        default: () => Date.now(),
    },
    updatedAt: Date,
});

export default mongoose.models?.User || mongoose.model("User", UserSchema);

该问题仅在中间件中出现,Server Components或Route Handlers中运行正常,使用版本:Next.js 14.1、Mongoose 8.2.0、MongoDB 6.0.13(Atlas集群)。

问题原因

核心原因是Next.js中间件运行在Edge Runtime环境,而Mongoose主要为Node.js Runtime设计,两者存在以下关键差异:

  • Edge Runtime不支持Node.js的部分核心API,Mongoose内部依赖的一些Node.js专属模块(如fs、net)在Edge环境中无法正常工作
  • 中间件的模块缓存机制与Node.js不同,mongoose.models?.User的判断逻辑在Edge环境下可能无法正确复用已创建的模型,导致模型初始化不完整,find等方法未被挂载
  • Mongoose 8.x对Edge Runtime的兼容性有限,官方尚未完全支持在Edge环境中使用完整的Mongoose功能

解决方案

方案1:将数据库查询逻辑移至Route Handler

中间件只负责路由拦截、权限校验等轻量逻辑,数据库查询通过调用内部Route Handler完成:

  1. 创建Route Handler(如app/api/get-user/route.ts):
import { NextResponse } from "next/server";
import User from "@/models/User";
import connectDB from "@/lib/db";

export async function GET(request: Request) {
  await connectDB();
  const { searchParams } = new URL(request.url);
  const id = searchParams.get("id");
  
  if (!id) {
    return NextResponse.json({ error: "Missing user ID" }, { status: 400 });
  }

  const user = await User.findOne({ _id: id });
  return NextResponse.json(user);
}
  1. 在中间件中调用该Handler:
try {
  const res = await fetch(`${process.env.NEXT_PUBLIC_APP_URL}/api/get-user?id=${id}`);
  const user = await res.json();
  console.log("user", user);
} catch (error: any) {
  throw new Error(error);
}

方案2:使用MongoDB官方驱动替代Mongoose

MongoDB官方的mongodb驱动对Edge Runtime兼容性更好,直接使用驱动进行查询:

import { MongoClient, ObjectId } from "mongodb";

const client = new MongoClient(process.env.MONGODB_URI!);

async function findUser({ id }: { id: string }) {
  await client.connect();
  const db = client.db(process.env.MONGODB_DB_NAME);
  const user = await db.collection("users").findOne({ _id: new ObjectId(id) });
  return user;
}

方案3:调整Mongoose使用方式(有限兼容)

如果坚持使用Mongoose,需确保在中间件中手动初始化模型,避免依赖全局缓存:

import mongoose from "mongoose";

// 直接创建模型,不依赖mongoose.models缓存
const UserSchema = new mongoose.Schema({ /* 你的Schema定义 */ });
const User = mongoose.model("User", UserSchema);

async function findUser({ id }: { id: string }) {
  await mongoose.connect(process.env.MONGODB_URI!);
  return User.find({ _id: id });
}

注意:这种方式可能仍存在Edge环境下的兼容性问题,建议优先使用前两种方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 20:38:26