Mongoose pre-hook 中的循环引用问题
Circular Reference Issue in Mongoose pre-hook
在我的 MongoDB/Node 后端环境中,我正在使用 Mongoose pre
和 post
钩子中间件来检查文档上发生了什么变化,以便创建一些系统结果注释。
我 运行 遇到的一个问题是,当我尝试查找相关文档的记录时,出现 "Customer.findOne()" is not a function
错误。当我从模型刚刚启动此 pre
和 post
挂钩触发器文件的同一集合中查找记录时,这只是一个问题。换句话说,如果我的 "Customer" 模型在外部文件的预挂钩函数中启动函数,那么如果我随后尝试使用标准 findOne()
查找 Customer
,我会收到错误消息:
我的客户模型看起来像这样:
module.exports = mongoose.model(
"Customer",
mongoose
.Schema(
{
__v: {
type: Number,
select: false
},
deleted: {
type: Boolean,
default: false
},
// Other props
searchResults: [
{
matchKey: String,
matchValue: String
}
]
},
{
timestamps: true
}
)
.pre("save", function(next) {
const doc = this;
trigger.preSave(doc);
next();
})
.post("save", function(doc) {
trigger.postSave(doc);
})
.post("update", function(doc) {
trigger.postSave(doc);
})
.post("findOneAndUpdate", function(doc) {
trigger.postSave(doc);
})
);
...从模型调用的 triggers
文件中有问题的 findOne()
函数如下所示:
const Customer = require("../../models/customer");
exports.preSave = async function(doc) {
this.preSaveDoc = await Customer.findOne({
_id: doc._id
}).exec();
};
澄清一下,如果我使用 findOne()
从同一个 triggers
文件中的不同集合中查找记录,这不是问题。然后它工作正常。找到 Contact
时见下文 -- 这里没问题:
const Contact = require("../../models/contact");
exports.preSave = async function(doc) {
this.preSaveDoc = await Contact.findOne({
_id: doc._id
}).exec();
};
我发现的解决方法是使用 Mongo 而不是 Mongoose,如下所示:
exports.preSave = async function(doc) {
let MongoClient = await require("../../config/database")();
let db = MongoClient.connection.db;
db.collection("customers")
.findOne({ _id: doc._id })
.then(doc => {
this.preSaveDoc = doc;
});
}
... 但我更愿意在这里使用 Mongoose 语法。如何在从与查找类型相同的 model/collection 调用的预挂钩函数中使用 findOne()
?
我 运行 几天前遇到过类似的问题。
实际上这是一个循环依赖问题。当您在客户模型上调用 .findOne() 时,它不存在,因为它尚未导出。
您或许应该尝试类似的方法:
const customerSchema = mongoose.Schema(...);
customerSchema.pre("save", async function(next) {
const customer = await Customer.findOne({
_id: this._id
}).exec();
trigger.setPreSaveDoc(customer);
next();
})
const Customer = mongoose.model("Customer", customerSchema)
module.export Customer;
这里会定义customer,因为它在创建之前没有被调用(pre hook)。
作为一种更简单的方法(我不确定)但您可以尝试将联系人导入移动到保存功能导出下的触发器文件中。这样我认为体面的做法可能会奏效。
有帮助吗?
在我的 MongoDB/Node 后端环境中,我正在使用 Mongoose pre
和 post
钩子中间件来检查文档上发生了什么变化,以便创建一些系统结果注释。
我 运行 遇到的一个问题是,当我尝试查找相关文档的记录时,出现 "Customer.findOne()" is not a function
错误。当我从模型刚刚启动此 pre
和 post
挂钩触发器文件的同一集合中查找记录时,这只是一个问题。换句话说,如果我的 "Customer" 模型在外部文件的预挂钩函数中启动函数,那么如果我随后尝试使用标准 findOne()
查找 Customer
,我会收到错误消息:
我的客户模型看起来像这样:
module.exports = mongoose.model(
"Customer",
mongoose
.Schema(
{
__v: {
type: Number,
select: false
},
deleted: {
type: Boolean,
default: false
},
// Other props
searchResults: [
{
matchKey: String,
matchValue: String
}
]
},
{
timestamps: true
}
)
.pre("save", function(next) {
const doc = this;
trigger.preSave(doc);
next();
})
.post("save", function(doc) {
trigger.postSave(doc);
})
.post("update", function(doc) {
trigger.postSave(doc);
})
.post("findOneAndUpdate", function(doc) {
trigger.postSave(doc);
})
);
...从模型调用的 triggers
文件中有问题的 findOne()
函数如下所示:
const Customer = require("../../models/customer");
exports.preSave = async function(doc) {
this.preSaveDoc = await Customer.findOne({
_id: doc._id
}).exec();
};
澄清一下,如果我使用 findOne()
从同一个 triggers
文件中的不同集合中查找记录,这不是问题。然后它工作正常。找到 Contact
时见下文 -- 这里没问题:
const Contact = require("../../models/contact");
exports.preSave = async function(doc) {
this.preSaveDoc = await Contact.findOne({
_id: doc._id
}).exec();
};
我发现的解决方法是使用 Mongo 而不是 Mongoose,如下所示:
exports.preSave = async function(doc) {
let MongoClient = await require("../../config/database")();
let db = MongoClient.connection.db;
db.collection("customers")
.findOne({ _id: doc._id })
.then(doc => {
this.preSaveDoc = doc;
});
}
... 但我更愿意在这里使用 Mongoose 语法。如何在从与查找类型相同的 model/collection 调用的预挂钩函数中使用 findOne()
?
我 运行 几天前遇到过类似的问题。 实际上这是一个循环依赖问题。当您在客户模型上调用 .findOne() 时,它不存在,因为它尚未导出。 您或许应该尝试类似的方法:
const customerSchema = mongoose.Schema(...);
customerSchema.pre("save", async function(next) {
const customer = await Customer.findOne({
_id: this._id
}).exec();
trigger.setPreSaveDoc(customer);
next();
})
const Customer = mongoose.model("Customer", customerSchema)
module.export Customer;
这里会定义customer,因为它在创建之前没有被调用(pre hook)。
作为一种更简单的方法(我不确定)但您可以尝试将联系人导入移动到保存功能导出下的触发器文件中。这样我认为体面的做法可能会奏效。
有帮助吗?