在nodejs中使用mongoose aggregate获取评论数据

1.解决问题:获取评论数组,数组中每个对象为一级评论,一级评论包含了一个数组,该数组为一级评论下的每个评论

2.预期结果:

 

3.代码

 find_discuss: async (id) => {
        //id:'文章'分类的id
        //temp用于存储一级评论
        let temp = []
        //deeplist:递归函数,parent_comment_id:传入上一级评论id,idx顶级评论当前索引值
        async function deeplist(parent_comment_id, idx = 0) {
            //aggregate集合管道,
            const comments = await Discuss_Model.aggregate([
                {
                    // 匹配一级评论
                    $match: { parent_comment_id: parent_comment_id, article_id: id }
                },
                {
                    /**
                     * 将$user_id转化为ObjectId对象,并添加为新字段:userIdObject,
                     * 此文档字段user_id为字符串类型与_id(ObjectId)类型进行匹配时需要转化,否则没有结果
                     */
                    $addFields: {
                        // 将 userId 转换为 ObjectId 类型
                        userIdObject: { $toObjectId: "$user_id" }
                    }
                },
                //联表查询,评论表和用户表
                {
                    $lookup: {
                        //联表查询的目标
                        from: "commonusers",
                        //当前表中需要进行关联的字段,
                        localField: "userIdObject",
                        //要被关联的表中的字段
                        foreignField: '_id',
                        //给结果数组字段取个名称
                        as: "user"
                    }
                },
                {// 展开数组,获取第一个匹配的用户信息
                    $unwind: '$user'
                },
                {
                    //最后返回前需要保留的字段,1保存,
                    $project: {
                        _id: 1,
                        article_id: 1,
                        user_id: 1,
                        comment_text: 1,
                        comment_date: 1,
                        parent_comment_id: 1,
                        'user.username': 1,
                        'user.avatar': 1
                    }
                }

            ])
            //如果parent_comment_id=''表示为一级评论
            if (parent_comment_id === '') {
                //拿到所有一级评论,存储给temp并为每个一级评论对象添加childs属性,并为[],用于存储子评论
                temp = comments
                for (let i = 0; i < temp.length; i++) {
                    temp[i].childs = []
                }
                return
            }
            //如果comments.length===0,该评论下已没有子评论,返回空数组
            if (comments.length === 0) {
                return []
            }
            //根据传入的idx,确保为当前一级评论,再对返回的评论数组进行合并
            temp[idx].childs = temp[idx].childs.concat(comments)
            for (let i = 0; i < comments.length; i++) {
                //确保合并数组之后,再根据当前返回的结果数组进行遍历,依次递归,找到以下所有评论
                await deeplist(comments[i]._id.toString(), idx)
            }
            //返回当前查询到的评论数组
            return comments
        }
        //先调用一次获取一级评论
        await deeplist('')
        //再遍历一级评论,传入一级评论_id和当前索引
        for (let i = 0; i < temp.length; i++) {
            await deeplist(temp[i]._id.toString(), i)
        }
        //返回最终的结果
        return temp

    },

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值