В моей бэкэнд-среде MongoDB / Node я использую промежуточное ПО Mongoose pre
и post
для проверки изменений в документе, чтобы в результате создать некоторые системные заметки.
Одна проблема, с которой я сталкиваюсь, заключается в том, что, когда я пытаюсь найти запись для рассматриваемого документа, я получаю ошибку "Customer.findOne()" is not a function
. Это ТОЛЬКО проблема, когда я ищу запись из той же коллекции, из которой модель только что запустила этот файл триггеров хуков pre
и post
. Другими словами, если моя модель «Клиент» запускает функции в функции предварительного подключения во внешнем файле, то я получаю ошибку, если затем пытаюсь найти Customer
со стандартным findOne()
:
Моя модель клиента выглядит примерно так:
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);
})
);
... проблемная функция findOne()
в файле triggers
, вызываемая из модели, выглядит следующим образом:
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 здесь. Как я могу использовать findOne()
в функции предварительного подключения, вызываемой из той же модели / коллекции, что и тип поиска?