查询另一个模型并在findOneAndUpdate插入之前添加引用

时间:2019-05-03 15:57:54

标签: javascript node.js mongodb mongoose

我有一个模型DotaStats,我正在尝试插入或更新该模型,并使用findOneAndUpdate查找。这种模型的新实例是通过upsert:true创建的。

我发现我可以在这个模型上使用虚函数进行很多计算工作,但是我不确定的一件事是如何引用另一个模型(不提供_id)。新创作。

我的用例是这样的,因为我不想在每个findOneAndUpdate请求中查询其他模型(游戏模型),因为在大多数情况下,这些请求只会被更新,而游戏引用不会每次都会更新。

这是我的代码。这是模型:

let mongoose = require('mongoose');
const Game = require('../Game');

let Schema = mongoose.Schema;

let schemaOptions = {
    toObject: {
        virtuals: true
    },
    toJSON: {
        virtuals: true
    }
};

//NOTE: Validate URL!
let DotaStatsSchema = new Schema({
    user: {
        type: Schema.ObjectId,
        ref: 'User',
        unique: true,
        required: true
    },
    game: {
        type: Schema.ObjectId,
        ref: 'Game',
    },
    updatedAt: {
        type: Date,
        required: true
    },
    rank: {
        type: Number,
        default: 0
    },
    mmrEstimate: {
        type: Number,
        default: 0
    },
    wins: {
        type: Number,
        default: 0
    },
    losses: {
        type: Number,
        default: 0
    },
    winPercentage: {
        type: Number
    },
    kills: {
        type: Number,
        default: 0
    },
    deaths: {
        type: Number,
        default: 0
    },
    assists: {
        type: Number,
        default: 0
    },
    kda: {
        type: Number
    },
    secondsPlayed: {
        type: Number,
        default: 0
    }
}, schemaOptions);

DotaStatsSchema.virtual('winPercentage').get(() => {
    return (this.wins / (this.wins + this.losses) * 100) ? (this.wins / (this.wins + this.losses) * 100).toFixed(2) : 0;
})

DotaStatsSchema.virtual('kda').get(() => {
    return ((this.kills + this.assists) / this.deaths) ? ((this.kills + this.assists) / this.deaths).toFixed(2) : 0;
})

let DotaStats = module.exports = mongoose.model('DotaStats', DotaStatsSchema);

这是我打电话给findOneAndUpdate的地方:

exports.handleDotaStats = (req, res, next) => {
    const newStats = {
        user: req.user._id,
        updatedAt: Date.now(),
        rank: req.body.rank,
        mmrEstimate: req.body.mmrEstimate,
        wins: req.body.wins,
        losses: req.body.losses,
        kills: req.body.kills,
        deaths: req.body.deaths,
        assists: req.body.assists,
        secondsPlayed: req.body.duration
    }

    DotaStats.findOneAndUpdate({
        user: req.user._id
    }, newStats, {
        upsert: true,
        new: true,
        rawResult: true
    }).then((stats) => {
        return res.json({
            success: true,
            message: 'Dota stats created, or updated, and found.',
            stats: stats
        })
    }).catch((err) => {
        res.send(err)
    })
}

我的理解是,您不能将.pre('save')或.pre('validate')方法与findOneAndUpdate一起使用,除了剩下的每次查询之外,我还有什么选择呢?

谢谢!

1 个答案:

答案 0 :(得分:0)

结束此操作,找到了一个足够体面的答案-使用findOneAndUpdate中提供的rawResult(或passRawResult)选项,您可以在请求后立即确定是否已对文档进行升级。现在已经足够了。