[英]ExpressJS/Mongoose two-way model communication
Say I have a User
model and a Book
model in my express app which both refer to each other - how can I use mongoose middleware to keep both models synced when saving either model? 假设我的Express应用程序中有一个
User
模型和一个Book
模型,它们两者相互引用-保存一个模型时,如何使用猫鼬中间件使两个模型保持同步?
I think it would be nice if I could use the following structure, so that when the name of a Book
is modified it's also updated on its author, the User
, and vice versa. 我认为如果可以使用以下结构会很好,这样一来,当修改
Book
的名称时,它的作者, User
也会随之更新,反之亦然。
The problem then of course is that the User
model is referencing the Book
model and the Book
model is referencing the User
model - a circular reference. 那么,问题当然是
User
模型引用了Book
模型,而Book
模型引用了User
模型-循环引用。 Is there any way to circumvent this in a neat and conventional way? 有什么方法可以以一种简洁而传统的方式规避这一问题?
user.model.js user.model.js
const { mongoose } = require('../db/mongoose');
const Schema = mongoose.Schema;
const Book = require('./book.model.js'); // <--- REFERENCING BOOK
const UserSchema = new Schema({
name: String,
books: [
{
_id: Schema.Types.ObjectId,
title: String,
},
],
});
UserSchema.pre('save', function() {
if (this.isModified('name')) {
Book.findAndUpdate({
'author._id': this._id,
}, {
// update name of book author
'author.name': this.name,
});
}
});
book.model.js book.model.js
const { mongoose } = require('../db/mongoose');
const Schema = mongoose.Schema;
const User = require('./user.model.js'); // <--- REFERENCING USER
BookSchema = new Schema({
title: String,
author: {
_id: Schema.Types.ObjectId,
name: String,
},
});
BookSchema.pre('save', function() {
if (this.isModified('title')) {
User.findByIdAndUpdate(this.author._id, {
// update the book title
...
});
}
});
My suggestion would be to actually create an association-collection UserBook
which you'll reference from both User
and Book
collections. 我的建议是实际创建一个关联集合
UserBook
,您将同时从User
和Book
集合中引用该集合。
UserBook
will contain two fields, one for the id of the book and the other for the id of the user . UserBook
将包含两个字段,一个字段为书籍的ID,另一个字段为user的ID。
As for the updates: you'll start by updating the association-collection and then propagate from it to both collections. 至于更新:您将从更新关联集合开始,然后将其从传播到两个集合。 Say you want, for example, to update a book, what you'll actually do is update the
UserBook
collection which you'll design in a why to launch updates, something like this: 举例来说,假设您要更新一本书,实际上要做的就是更新您要设计的
UserBook
集合,以说明为什么要启动更新,如下所示:
The documentation for middleware/hooks states that: 中间件/挂钩的文档指出:
Pre and post
save()
hooks are not executed onupdate()
,findOneAndUpdate()
, etc.在
update()
,findOneAndUpdate()
等上不执行pre和postsave()
挂钩。
Therefore, a call to book.save();
因此,调用
book.save();
should not trigger the save-middleware of it's user
. 不应触发
user
的保存中间件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.