const mongoose = require('mongoose'); const blogTagSchema = new mongoose.Schema({ name: { type: String, required: true, trim: true, unique: true // "WorkVisa" }, slug: { type: String, required: true, unique: true, trim: true // "work-visa" }, postCount: { type: Number, default: 0 }, isActive: { type: Boolean, default: true } }, { timestamps: true }); // Indexes blogTagSchema.index({ isActive: 1, name: 1 }); // Remove __v from JSON output blogTagSchema.set('toJSON', { transform: function(doc, ret) { delete ret.__v; return ret; } }); // Pre-save middleware blogTagSchema.pre('save', function(next) { // Auto-generate slug if not provided if (!this.slug && this.name) { this.slug = this.name .toLowerCase() .replace(/[^a-z0-9\s-]/g, '') .replace(/\s+/g, '-') .replace(/-+/g, '-') .trim('-'); } next(); }); // Static methods blogTagSchema.statics.getActive = function() { return this.find({ isActive: true }).sort({ name: 1 }); }; blogTagSchema.statics.getPopular = function(limit = 10) { return this.find({ isActive: true }) .sort({ postCount: -1, name: 1 }) .limit(limit); }; // Method to update post count blogTagSchema.methods.updatePostCount = async function() { const Blog = require('./blog'); const count = await Blog.countDocuments({ tags: { $in: [this.name] }, // Tìm trong array tags status: 'published' }); this.postCount = count; await this.save(); return count; }; module.exports = mongoose.model('BlogTag', blogTagSchema);