如何在Mongoose中修改name时自动用slugify更新slug?
解决修改产品名称后Slug不自动更新的问题
你的问题出在当前仅使用了pre('save')中间件,这个中间件只在调用Document.save()方法时触发。但实际开发中更新产品常使用findByIdAndUpdate、updateOne这类查询式更新方法,这些方法不会触发save钩子,导致slug无法同步更新。另外,每次save都更新slug也没必要,建议仅在name字段修改时才更新。
以下是修改后的完整代码:
const mongoose = require('mongoose'); const { default: slugify } = require('slugify'); const ProductSchema = new mongoose.Schema( { name: { type: String, trim: true, unique: true, required: [true, 'Please add product name'], }, slug: String, sku: { type: String, trim: true, required: [true, 'Please add product sku'], }, isActive: { type: Boolean, default: true, }, createdAt: { type: Date, default: Date.now, }, updatedAt: { type: Date, default: Date.now, }, }, { toJSON: { virtuals: true }, toObject: { virtuals: true }, } ); // 处理save场景:仅当name字段修改时更新slug ProductSchema.pre('save', function (next) { if (this.isModified('name')) { this.slug = slugify(this.name, { lower: true }); this.updatedAt = Date.now(); } next(); }); // 处理findByIdAndUpdate、findOneAndUpdate场景 ProductSchema.pre('findOneAndUpdate', function (next) { const update = this.getUpdate(); if (update.name) { update.slug = slugify(update.name, { lower: true }); update.updatedAt = Date.now(); } next(); }); // 处理updateOne、updateMany场景 ProductSchema.pre('updateOne', function (next) { const update = this.getUpdate(); if (update.name) { update.slug = slugify(update.name, { lower: true }); update.updatedAt = Date.now(); } next(); }); // 修正原代码模型名拼写错误:Prduct → Product module.exports = mongoose.model('Product', ProductSchema);
关键修改说明:
- save钩子优化:用
this.isModified('name')判断name是否被修改,仅在修改时更新slug和updatedAt字段,避免无意义的重复操作。 - 新增查询更新钩子:添加
pre('findOneAndUpdate')和pre('updateOne')钩子,覆盖常用的查询式更新方法,检测name是否被更新后同步生成新slug并更新时间戳。 - 模型名修正:原代码中模型名
Prduct为拼写错误,修正为Product,避免后续调用模型时出现异常。
内容的提问来源于stack exchange,提问作者Sakhawat Hossain Sohel
相关产品推荐
相关产品推荐

