Mongoose pre-hook 中的循环引用问题

Circular Reference Issue in Mongoose pre-hook

在我的 MongoDB/Node 后端环境中,我正在使用 Mongoose prepost 钩子中间件来检查文档上发生了什么变化,以便创建一些系统结果注释。

我 运行 遇到的一个问题是,当我尝试查找相关文档的记录时,出现 "Customer.findOne()" is not a function 错误。当我从模型刚刚启动此 prepost 挂钩触发器文件的同一集合中查找记录时,这只是一个问题。换句话说,如果我的 "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)。

作为一种更简单的方法(我不确定)但您可以尝试将联系人导入移动到保存功能导出下的触发器文件中。这样我认为体面的做法可能会奏效。

有帮助吗?