mongoose 实现评论功能(一级和二级评论)

创建数据,可以创建一级和二级评论, 查询返回数据整合数据返回,具体实现效果如下。具体启动node,连接mongodb ,创建router,controller等操作自行处理。
  • 最终的数据结构
    在这里插入图片描述

1. 创建model

一级评论 parentId:0, 二级评论为 parentId:_id
from to 可以关联User表,这里为了演示,只当输入字段处理

const mongoose = require('mongoose');
const { Schema, model } = mongoose;

const commentSchema = new Schema({
    // 标题
    title: { type: String, required: true },
    // 评论人
    from: { type: String, required: true },
    // 回复哪一位
    to: { type: String, required: false },
    // 评论内容
    content: { type: String, required: true },
    // 父级id
    parentId: { type: String, required: true, default: 0 },

}, { timestamps: true });

module.exports = model('Comment', commentSchema);
  • 工具函数
class Utils {
    CallbackModel(ctx, status, message, data) {
        ctx.response.status = status;
        ctx.body = {
            code: status,
            message: message,
            data: data,
        };
    }
}

module.exports = new Utils;

2. 创建评论( controller )

const Comment = require('../models/comments');
const { CallbackModel } = require('../utils')

    // 新增
    async create(ctx) {
        try {
            const data = await new Comment({...ctx.request.body }).save();
            CallbackModel(ctx, 200, '创建评论成功', data)
        } catch (error) {
            CallbackModel(ctx, 500, '错误', JSON.stringify(error))
        }
    }

  • 测试数据如下:
            {
                "_id": "5de601beec1c98861c9c3aaa",
                "parentId": "0",
                "content": "我看看吧",
                "from": "zhaohang",
                "to": "",
                "title": "尼玛 今年的天气有点冷啊",
                "createdAt": "2019-12-03T06:33:34.320Z",
                "updatedAt": "2019-12-03T06:33:34.320Z",
            },
			{
			    "_id": "5de601d2ec1c98861c9c3aab",
                "parentId": "0",
                "content": "很好啊",
                "from": "admin",
                "to": "",
                "title": "尼玛 今年的天气有点冷啊",
                "createdAt": "2019-12-03T06:33:54.549Z",
                "updatedAt": "2019-12-03T06:33:54.549Z",
			},
			{
			    "_id": "5de601f3ec1c98861c9c3aac",
                "parentId": "5de601d2ec1c98861c9c3aab",
                "content": "好像确实有点冷呢",
                "from": "alex",
                "to": "admin",
                "title": "尼玛 今年的天气有点冷啊",
                "createdAt": "2019-12-03T06:34:27.453Z",
                "updatedAt": "2019-12-03T06:34:27.453Z"
			}
			
			......
			

3. 查询评论列表

  • 涉及到知识点
  1. 异步回调问题
  2. 返回数据修改
  3. 过滤数据,分页,模糊搜索,排序
 	// 查询
    async list(ctx) {
        try {
            const { per_page = 1, page_size = 10, q = '' } = ctx.query;
            let filterData = { content: new RegExp(q) }

            var query = Comment
                .find({ parentId: 0, ...filterData }).select('-__v')

            var data = await query
                .sort({ createdAt: 1 })
                .limit(+page_size)
                .skip((+per_page - 1) * +page_size)
                .lean();
                
            var count = await query.count();
            
          	// 处理异步回调
            var promises = data.map(item => {
                return Comment.find({
                    parentId: item._id
                }).select('-__v').lean()
            });
            
            var list = await Promise.all(promises)
            
            data.forEach(item => {
                list.forEach(code => {
                    if (code.length > 0 && item._id == code[0].parentId) {
                        item.items = code
                    } else {
                        item.items = []
                    }
                })
            })
            CallbackModel(ctx, 200, '查询评论列表成功', { list: data, count })
        } catch (error) {
            CallbackModel(ctx, 500, '错误', JSON.stringify(error))
        }
    }
  1. 第一步操作查询一级评论(parentId:0),二级评论的查询条件是基于一级评论来返回,由于异步问题,需要使用Promise.all来配合,不然都是查询到空数组。
  2. 对返回数据进行操作,我们需要在返回的结构里面多添加一个key:value的,由于model已经定义好的格式,我们无法直接修改数据,我们对查询数据使用lean()的方法,即可直接修改里面的数据。
  3. 对一级和二级数据整合,他们之间的纽带是parentId
  4. select 的方法使用:解释=>返回test字段:select(’+test’) 或者 不返回test字段:select(’-test’)
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值