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

Mongoose自定义方法仅Schema选项方式生效,另外两种方法失效求助

问题

根据Mongoose文档,给文档添加自定义方法有3种方式:1.通过Schema选项;2.直接给Schema赋值methods对象;3.使用Schema.method()助手。但多次尝试后仅第一种方式生效,另外两种调用时提示‘不是函数’。

相关代码如下:

app.js

socket.on("message", async function (clusterData, callback) {
  console.log("socket event fired");
  const parentCluster = await Message.findById(clusterData.clusterId);
  console.log(parentCluster); // 如预期存在

  parentCluster.optionsMethod(); // 日志:"options method called" ✔
  parentCluster.objectMethod(); // 错误:parentCluster.objectMethod is not a function ❌
  parentCluster.helperMethod(); // 错误:parentCluster.helperMethod is not a function ❌
});

Message.js

import mongoose from "mongoose";

const messageSchema = new mongoose.Schema({
  mentions: [{ type: mongoose.Schema.Types.ObjectId, ref: "User" }],
  text: { type: String, trim: true },
  file: { type: String },
  dateString: { type: String, required: true },
  timestamp: { type: Number, required: true },
});

const messageClusterSchema = new mongoose.Schema(
  {
    sender: {
      type: mongoose.Schema.Types.ObjectId,
      ref: "User",
      required: true,
    },
    channel: {
      type: mongoose.Schema.Types.ObjectId,
      ref: "Channel",
      required: true,
    },
    group: {
      type: mongoose.Schema.Types.ObjectId,
      ref: "Group",
      required: true,
    },
    content: [messageSchema],
    clusterTimestamp: {
      type: Number,
      required: true,
    },
  },
  {
    toObject: { virtuals: true },
    toJSON: { virtuals: true },
    methods: {
      optionsMethod() {
        console.log("options method called");
      },
    },
  }
);
messageClusterSchema.virtual("lastMessage").get(function () {
  return this.content[this.content.length - 1];
});

messageClusterSchema.pre("validate", function () {
  console.log("pre validate ran");
  this.clusterTimestamp = this.content[this.content.length - 1].timestamp;
});


// 直接赋值给对象
messageSchema.methods.objectMethod = function () {
  console.log("object method called");
};

// 使用助手赋值
messageSchema.method("helperMethod", function () {
  console.log("helper method called");
});

console.log(messageSchema.methods); // {objectMethod: [Function (anonymous)], helperMethod: [Function (anonymous)]}
console.log(messageSchema.methodOptions); // { helperMethod: undefined }

const Message = mongoose.model("Message", messageClusterSchema);

export default Message;
原因与解决方法

你把objectMethod和helperMethod定义在了**messageSchema上,但你的Message模型是基于messageClusterSchema**创建的。通过Message.findById()获取的parentCluster是messageClusterSchema的实例,而非messageSchema的实例,因此调用这两个方法时会提示“不是函数”。

只需将方法定义转移到messageClusterSchema上即可解决问题:

// 直接赋值给对象
messageClusterSchema.methods.objectMethod = function () {
  console.log("object method called");
};

// 使用助手赋值
messageClusterSchema.method("helperMethod", function () {
  console.log("helper method called");
});

修改后,parentCluster.objectMethod()和parentCluster.helperMethod()就能正常执行了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 07:05:16