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
相关产品推荐
相关产品推荐

