В mongoose установить поле на основе значения другого поля в findOneAndUpdate - PullRequest
0 голосов
/ 21 февраля 2019

Я работаю над проектом, в котором в одной модели мне нужно установить значение поля на основе значения другого поля.Позвольте мне объяснить с помощью некоторого кода.

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.from или Task.to на другой destination, затем мне нужно снова пересчитать приоритет задач.Я мог бы сделать это на стороне клиента, но это привело бы к проблеме, когда можно было просто отправить priority в запросе на обновление на сервер.

Мой вопрос здесь, как я могу вычислитьприоритет Task, когда он обновляется новыми значениями для from и to?Нужно ли запрашивать документ, который скоро будет обновлен, чтобы получить ссылку на него, или есть другой более чистый способ сделать это, поскольку это приведет к одному дополнительному попаданию в базу данных, и я пытаюсь избежать этогокак можно больше.

...