NodeJS 在mongoose中,根据findOneAndUpdate中另一个字段的值设置字段

xxhby3vn  于 2023-01-25  发布在  Node.js
关注(0)|答案(1)|浏览(132)

我正在做一个项目,在一个模型中,我需要根据另一个字段的值来设置另一个字段的值。让我用一些代码来解释。
Destination model

const mongoose = require('mongoose');

const Schema = mongoose.Schema;

const DestinationSchema = new Schema({
    name: {
        type: String, 
        required: true 
    },
    priority: {
        type: Number,
        default: 0,
        max: 10,
        required: true
    }
})

DestinationSchema.statics.getPriority = function(value) {
    return this.findOne({ _id: value })
}

const Destination = mongoose.model('Destination', DestinationSchema)

exports.Destination =  Destination

Task model

const mongoose = require('mongoose')
const { Destination } = require('../_models/destination.model')

const Schema = mongoose.Schema;

const TaskSchema = new Schema({
    priority: {
        type: Number,
        required: true,
        min: 0,
        max: 25
    },
    from: {
        type: Schema.Types.ObjectId,
        ref: 'Destination',
        required: true
    },
    to: {
        type: Schema.Types.ObjectId,
        ref: 'Destination',
        required: true
    },
    type: {
        type: Number,
        required: true,
        min: 0,
        max: 3
    }
}, { 
    timestamps: true
})

TaskSchema.pre('save', async function () {
    this.priority = await Destination.getPriority(this.from).then(doc => {
        return doc.priority
    })

    this.priority += await Destination.getPriority(this.to).then(doc => {
        return doc.priority
    })

    this.priority += this.type
})

Task Controller update function

exports.update = async function (req, res) {
    try {
        await Task.findOneAndUpdate({
                _id: req.task._id
            }, { $set: req.body }, {
                new: true,
                context: 'query'
            })
            .then(task =>
                sendSuccess(res, 201, 'Task updated.')({
                    task
                }),
                throwError(500, 'sequelize error')
            )
    } catch (e) {
        sendError(res)(e)
    }
}

当我创建一个新的任务时,优先级在预保存钩子中设置得很好,正如预期的那样。但是当我需要将Task.fromTask.to更改为另一个destination时,我遇到了障碍,然后我需要再次重新计算任务的优先级。我可以在客户端完成它。但是这将导致人们可能仅仅在更新查询中向服务器发送priority的问题。
这里我的问题是,当fromto的值被更新时,我如何计算Task的优先级?我是否必须查询将要更新的文档以获得对它的引用,或者是否有其他更干净的方法来完成,因为这将导致对数据库的额外命中,我正在尽可能地避免它。

h7appiyu

h7appiyu1#

在任务架构中。
你必须使用pre("findOneAndUpdate") mongoose中间件,它允许你在执行之前修改更新查询
验证码:

TaskSchema.pre('findOneAndUpdate', async function(next) {
    if(this._update.from || this._update.to) {
        if(this._update.from) {
            this._update.priority = await Destination.getPriority(this._update.from).then(doc => {
                return doc.priority
            });
        }
        if(this._update.to) {
            this._update.priority += await Destination.getPriority(this._update.to).then(doc => {
                return doc.priority
            });
        }
    }
    next();
});

相关问题