如何将Mongoose模型中某字段值设置为另外两个字段的和?
实现Mongoose中total字段自动计算wallet与bank之和
如果需要让total字段始终等于wallet和bank的数值之和,推荐两种常用实现方式:
方式一:用虚拟字段(不存到数据库)
这种方式下total不会被持久化到数据库,每次访问时实时计算,适合只需要获取总和、不需要存储的场景。修改你的Schema如下:
const mongoose = require('mongoose'); const User = new mongoose.Schema({ id: { type: String, unique: true, required: true }, wallet: { type: Number, default: 500 }, bank: { type: Number, default: 0 } }, { // 开启虚拟字段的序列化,确保查询结果转JSON/对象时能看到total toJSON: { virtuals: true }, toObject: { virtuals: true } }); // 定义虚拟字段total,每次访问时自动计算总和 User.virtual('total').get(function() { return this.wallet + this.bank; }); module.exports = { User: mongoose.model("User", User) }
使用时直接访问user.total就能拿到实时计算的总和,不需要手动维护。
方式二:用预保存钩子(把total存到数据库)
如果必须将total存储到数据库里,就用Mongoose的预保存中间件,在文档保存或更新时自动计算并赋值:
const mongoose = require('mongoose'); const User = new mongoose.Schema({ id: { type: String, unique: true, required: true }, wallet: { type: Number, default: 500 }, bank: { type: Number, default: 0 }, total: { type: Number } }); // 保存前自动计算total User.pre('save', function(next) { this.total = this.wallet + this.bank; next(); }); // 注意:updateOne这类更新方法不会触发save钩子,所以要单独处理 User.pre('updateOne', function(next) { const updateData = this.getUpdate(); // 只有当wallet或bank被更新时,才重新计算total if (updateData.wallet !== undefined || updateData.bank !== undefined) { this.model.findOne(this.getQuery()).then(doc => { const newWallet = updateData.wallet ?? doc.wallet; const newBank = updateData.bank ?? doc.bank; this.setUpdate({ ...updateData, total: newWallet + newBank }); next(); }).catch(err => next(err)); } else { next(); } }); module.exports = { User: mongoose.model("User", User) }
这样无论是创建文档、调用save()更新,还是用updateOne更新,total都会自动保持为wallet和bank的和。
内容的提问来源于stack exchange,提问作者Harsh Agrawal
相关产品推荐
相关产品推荐

