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

Next.js中仅用类而非实例时findOneAndUpdate无法工作

问题:Mongoose findOneAndUpdate 提示“不是函数”错误

控制台已确认MongoDB连接成功,但调用使用findOneAndUpdate的updateUser函数时,出现以下错误:

Failed to create/update user: _models_user_model__WEBPACK_IMPORTED_MODULE_1__.default.findOneAndUpdate is not a function
TypeError: _models_user_model__WEBPACK_IMPORTED_MODULE_1__.default.findOneAndUpdate is not a function

相关代码

updateUser 函数

import { revalidatePath } from "next/cache";
import User from "../models/user.model";
import { connectToDB } from "../mongoose";

interface Params {
  userId: string;
  username: string;
  name: string;
  bio: string;
  image: string;
  path: string;
}

export async function updateUser({
  userId,
  username,
  name,
  bio,
  image,
  path,
}: Params): Promise<void> {
  try {
    // 建立数据库连接
    await connectToDB();
    // 更新用户文档
    console.log(`Modelo ${User}`)
    await User.findOneAndUpdate(
      { id: userId },
      {
        username: username.toLowerCase(),
        name,
        bio,
        image,
        onboarded: true,
      },
      { upsert: true }
    );

    // 必要时重新验证路径
    if (path === "/profile/edit") {
      revalidatePath(path);
    }
  } catch (error: any) {
    // 记录错误用于调试
    console.error(`Failed to create/update user: ${error.message}`);
    // 可选:重新抛出错误以便在其他地方处理
    throw error;
  }
}

用户模型(user.model.ts)

import mongoose from "mongoose";

const userSchema = new mongoose.Schema({
  id: {
    type: String,
    required: true,
  },
  username: {
    type: String,
    unique: true,
    required: true,
  },
  name: {
    type: String,
    required: true,
  },
  image: String,
  bio: String,
  threads: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: "Thread",
    },
  ],
  onboarded: {
    type: Boolean,
    default: false,
  },
  communities: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: "Community",
    },
  ],
});

const User = mongoose.models?.User || mongoose.model('User', userSchema);
export default User;

MongoDB 连接文件(mongoose.ts)

"use server"
import mongoose from "mongoose";

let isConnected = false; // 跟踪连接状态的变量

export const connectToDB = async () => {
  // 设置严格查询模式,防止未知字段查询
  if (!process.env.NEXT_PUBLIC_MONGODB_URL) return console.log("Missing MongoDB URL");

  // 如果连接已建立,无需创建新连接
  if (isConnected) {
    console.log("MongoDB connection already established");
    return;
  }

  try {
    await mongoose.connect(process.env.NEXT_PUBLIC_MONGODB_URL);
    mongoose.set('strictQuery', false);

    isConnected = true; // 将连接状态设为已连接
    console.log("MongoDB connected");
    console.log(mongoose.models);

  } catch (error) {
    console.log(error);
  }
};

预期与实际情况

预期流程:

  1. 成功建立MongoDB连接
  2. 通过findOneAndUpdate按ID查找并更新用户文档
  3. 必要时重新验证路径
  4. 处理更新中的错误

实际情况:连接正常,但findOneAndUpdate被提示不是函数,无法完成更新操作。


解决方案

1. 修正模型导出逻辑

Next.js服务端环境的模块缓存可能导致模型重复定义或未正确初始化,修改用户模型的导出代码,确保模型只被创建一次:

import mongoose from "mongoose";

const userSchema = new mongoose.Schema({
  // 保留原有字段定义
});

// 优先使用已存在的模型,避免重复创建
export default mongoose.models.User || mongoose.model('User', userSchema);

2. 确保连接完成后模型已加载

在connectToDB函数中添加模型存在性检查,避免未加载模型就执行操作:

"use server"
import mongoose from "mongoose";
import { userSchema } from "../models/user.model"; // 导入Schema

let isConnected = false;

export const connectToDB = async () => {
  if (!process.env.NEXT_PUBLIC_MONGODB_URL) return console.log("Missing MongoDB URL");
  
  if (isConnected) {
    // 确认User模型已加载
    if (!mongoose.models.User) {
      mongoose.model('User', userSchema);
    }
    console.log("MongoDB connection already established");
    return;
  }

  try {
    await mongoose.connect(process.env.NEXT_PUBLIC_MONGODB_URL);
    mongoose.set('strictQuery', false);
    // 显式创建模型(如果未自动创建)
    if (!mongoose.models.User) {
      mongoose.model('User', userSchema);
    }
    isConnected = true;
    console.log("MongoDB connected");
    console.log(mongoose.models);
  } catch (error) {
    console.log(error);
  }
};

3. 检查查询条件正确性

确认查询条件与模型定义匹配:当前使用{ id: userId },模型中确实定义了自定义id字段,这部分没问题;如果使用的是MongoDB默认的_id,则需要改为{ _id: userId }。

4. 重启开发服务器

Next.js的模块缓存可能保留旧的模型代码,重启服务器可清除缓存,确保最新的模型代码被加载。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 14:47:32