最近,闲着没事,又把上个月写得代码拿出来了,随便完善一下没完成的评论的路由接口。html
评论应该是在整个博客数据存储中,模型最为复杂的一部分了。首先要考虑的是和文章进行关联。这个能够用 mongoDB 的 ref
进行关联,随后可使用 populate
计算出被关联的字段。前端
最后关系复杂的是父子层级的评论,又或者是多级评论。这个时候就要想该怎么作才能合理的管理这些层级关系,在删除父评论的同时又能把全部子评论一块儿删除。查询的时候如何去由根到叶顺序输出层级关系。git
const schema = new mongoose.Schema({ // comment id cid: { type: Number, required: true, unique: true }, // post id pid: { type: Number, required: true }, post: { type: mongoose.SchemaTypes.ObjectId, ref: 'Post' }, content: { type: String, required: true }, createTime: { type: Number, default: Date.now() }, author: { type: String, required: true }, owner: { type: String, required: true }, isOwner: { type: Boolean, required: true }, email: { type: String }, url: { type: String }, key: { type: String, required: true, unique: true }, parent: { type: mongoose.SchemaTypes.ObjectId, ref: 'Comment' }, hasChild: { type: Boolean, default: false }, ipAddress: { type: String, required: true }, userAgent: { type: String }, // 0 审核 1 发布 2 垃圾 state: { type: Number, required: true, default: 0 } })
在模型中,post
列中关联引用表(post表)的 _id
(文章),在 hasChild
中记录是否存在回复。在后期处理回复路由的时候不要忘记修改他的值。最关键的是 key
列,这个用来记录平行层级。如 post
中的一篇 pid 为 11
的文章下有一条评论,那么 key
中命名 11#001
,这是第一条评论,若是该评论下存在一条回复,则回复的 key
为 11#001#001
,下层亦是如此。使用该命名方式能够容纳的每条评论的回复量为 999,能够根据需求调整0的数量。github
在创建记录的时候就把后期须要用到的slug直接生成,方便了前端的调用。这是一个缘由。固然这不是重点,经过层次命名的 key,对删除父评论至关方便。例以下图所示的关系层级。数据库
而后删除 key 为 11#001
的评论只要使用正则匹配 /^11#001/
便可,把匹配到的内容所有删除就能够不用管关联的 post
是否一致,以及 cid
,而 key
的值能够从前端发起的请求中提取 cid
,用 cid
去查这个惟一记录,从中拿到咱们须要的 key。async
参考删除评论路由以下mongoose
router.delete('/', async (req, res) => { const id = req.query.id if (id) { const isCid = id.length !== 24 ? true : false try { const query = await Comment.findOneAndDelete({ cid: id }).populate('post') if (query) { if (query.hasChild) { const delCount = (await Comment.deleteMany({ key: new RegExp(`^${query.key}`, 'ig') })).deletedCount + 1 } await User.updateOne( { username: req.username }, { $inc: { 'options.comments_nums': -(delCount || 1) } } ) // 删除post中的comments数量 query.post.comments -= delCount || 1 await query.post.save() } return res.send({ ok: 1, n: 1, deleteCount: delCount || 1 }) } catch (e) { console.log(e) return res.send({ ok: 0, msg: '参数不正确' }) } } return res.send({ ok: 0, msg: '请输入正确的ID' }) })
说完了删除,相比之下新建评论就容易多了,只要根据本来的评论数量设定新的 key 就好了。可使用模型提供的方法 countDocument()
。post
const body = req.body const comments = await Comment.countDocuments({ pid, key: new RegExp(`^${pid}#\\d\\d\\d$`) }) body.key = String(pid) + `#${String(comments + 1).padStart(3, 0)}`
最后,看看数据库中的记录如何。学习
初心者,一块儿学习,欢迎指出不足。
转载于个人博客 对博客中评论的合理建模 --MongoDB