基于MongoDB+Express.js实现分类删除时同步删除关联交易记录
删除分类时同步删除关联交易的实现方案
基于现有Schema的实现方案
你的当前Schema中,Transaction通过category字符串字段关联Category的title,可以通过以下Express路由实现批量删除:
路由代码
const express = require('express'); const router = express.Router(); const Category = require('../models/Category'); const Transaction = require('../models/Transaction'); // 删除指定分类及关联交易 router.delete('/categories/:categoryTitle', async (req, res) => { const { categoryTitle } = req.params; try { // 1. 删除目标分类 const deletedCategory = await Category.findOneAndDelete({ title: categoryTitle }); if (!deletedCategory) { return res.status(404).json({ message: '分类不存在' }); } // 2. 删除所有关联该分类的交易 const deletedTransactions = await Transaction.deleteMany({ category: categoryTitle }); res.status(200).json({ message: '分类及关联交易删除成功', deletedCategory, deletedTransactionCount: deletedTransactions.deletedCount }); } catch (err) { console.error('删除失败:', err); res.status(500).json({ message: '服务器内部错误' }); } }); module.exports = router;
更规范的关联优化方案
用字符串title关联容易出现重复或不一致问题,更推荐用MongoDB的ObjectId建立关联:
修改Schema
// TransactionSchema const schema = mongoose.Schema({ title: String, createdDate: Date, amount: Number, expenseType: String, category: { type: mongoose.Schema.Types.ObjectId, ref: 'Category' // 关联Category模型 } }) // CategorySchema 保持不变(mongoose默认自动生成_id) const schema = mongoose.Schema({ title: String, createdDate: Date, })
优化后的删除路由
router.delete('/categories/:categoryId', async (req, res) => { const { categoryId } = req.params; try { const deletedCategory = await Category.findByIdAndDelete(categoryId); if (!deletedCategory) { return res.status(404).json({ message: '分类不存在' }); } const deletedTransactions = await Transaction.deleteMany({ category: categoryId }); res.status(200).json({ message: '删除成功', deletedCategory, deletedTransactionCount: deletedTransactions.deletedCount }); } catch (err) { console.error('删除失败:', err); res.status(500).json({ message: '服务器内部错误' }); } });
原子性保障(生产环境建议)
如果需要保证“分类删除”和“交易删除”两个操作要么都成功、要么都失败,避免数据不一致,可以使用MongoDB事务(需要MongoDB副本集/分片集群环境):
router.delete('/categories/:categoryId', async (req, res) => { const { categoryId } = req.params; const session = await mongoose.startSession(); session.startTransaction(); try { // 在事务中执行删除操作 const deletedCategory = await Category.findByIdAndDelete(categoryId, { session }); if (!deletedCategory) { await session.abortTransaction(); session.endSession(); return res.status(404).json({ message: '分类不存在' }); } const deletedTransactions = await Transaction.deleteMany({ category: categoryId }, { session }); // 提交事务 await session.commitTransaction(); session.endSession(); res.status(200).json({ message: '删除成功', deletedCategory, deletedTransactionCount: deletedTransactions.deletedCount }); } catch (err) { // 回滚事务 await session.abortTransaction(); session.endSession(); console.error('删除失败:', err); res.status(500).json({ message: '服务器内部错误' }); } });
内容的提问来源于stack exchange,提问作者afnan
相关产品推荐
相关产品推荐

