简体   繁体   English

ExpressJS / Mongoose双向模型通信

[英]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 ,您将同时从UserBook集合中引用该集合。

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 on update() , findOneAndUpdate() , etc. update()findOneAndUpdate()等上不执行pre和post save()挂钩。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM