Bootstrap

node.js使用mongoose,8个表联合查询,返回分页记录及记录总数

// 获取所有学生的学分,使用authToken验证客户端发送的token是否过期
router.post('/admpoint/getAllPoints', [authToken], async (req, res) => {
    try {
        const { page, pagesize, activityCategoryInfo, itemCategoryInfo, itemInfo, studentInfo, collegeInfo } = req.body
        // 生成搜索条件对象
        let searchData = {}

        if (activityCategoryInfo) {
            searchData.activityCategoryInfo = activityCategoryInfo
        }
        if (itemCategoryInfo) {
            searchData.itemCategoryInfo = itemCategoryInfo
        }
        if (itemInfo) {
            searchData.itemInfo = itemInfo
        }
        if (studentInfo) {
            searchData.studentInfo = new ObjectId(studentInfo)
        }    
        if (collegeInfo) {
            searchData.collegeInfo = new ObjectId(collegeInfo)
        }
        // 多表联合查询
        let result = await studentPoints.aggregate([
            {
                $lookup: {// 获取学生信息
                    from: "students",
                    localField: "studentInfo",
                    foreignField: "_id",
                    as: "stuInfo",
                    pipeline: [// 学生表中,存有学院_id、专业的_id、班级_id,因此还需要和这三个表联合查询获取学院专业班级信息
                        {
                            $lookup: {//获取学院
                                from: "colleges",
                                localField: "collegeInfo",
                                foreignField: "_id",
                                as: "college_name",
                                pipeline: [
                                    {
                                        $project: {
                                            _id: 0,
                                            __v: 0
                                        }
                                    }
                                ]
                            }
                        },
                        {
                            $lookup: { //获取专业
                                from: "majors",
                                localField: "majorInfo",
                                foreignField: "_id",
                                as: "majInfo",
                                pipeline: [
                                    {
                                        $project: {
                                            _id: 0, // 不返回_id字段
                                            major: 1, // 返回major字段
                                        }
                                    }
                                ]
                            }
                        },
                        {
                            $lookup: { //获取班级
                                from: "grades",
                                localField: "gradeInfo",
                                foreignField: "_id",
                                as: "grdInfo",
                                pipeline: [
                                    {
                                        $project: {
                                            _id: 0, // 不返回_id字段
                                            grade: 1, // 返回grade字段
                                            year: 1
                                        }
                                    }
                                ]
                            }
                        },
                        {//通过以下方法,将college_name中的内容提取出来,放到记录的根节点
                            $replaceRoot: { newRoot: { $mergeObjects: [{ $arrayElemAt: ["$college_name", 0] }, "$$ROOT"] } }
                        },
                        {//通过以下方法,将majInfo中的内容提取出来,放到记录的根节点
                            $replaceRoot: { newRoot: { $mergeObjects: [{ $arrayElemAt: ["$majInfo", 0] }, "$$ROOT"] } }
                        },
                        {//通过以下方法,将grdInfo中的内容提取出来,放到记录的根节点
                            $replaceRoot: { newRoot: { $mergeObjects: [{ $arrayElemAt: ["$grdInfo", 0] }, "$$ROOT"] } }
                        },
                        { // 通过以上方法,从college_name majInfo等中提取出了字段并放在了根节点,此时college_name majInfo等就不需要了,以下可屏蔽college_name等
                            $project: {
                                college_name: 0,
                                majInfo: 0,
                                grdInfo: 0,
                                _id: 0,
                                __v: 0,
                                password: 0,
                                points: 0,
                                year: 0,
                                role: 0
                            }
                        },
                    ]
                }
            },
            {//通过以下方法,将stuInfo中的内容提取出来,放到记录的根节点
                $replaceRoot: { newRoot: { $mergeObjects: [{ $arrayElemAt: ["$stuInfo", 0] }, "$$ROOT"] } }
            },
            {
                $lookup: {// 获取活动大类信息
                    from: "activitycategories",
                    localField: "activityCategoryInfo",
                    foreignField: "_id",
                    as: "actInfo",
                    pipeline: [
                        {
                            $project: {
                                _id: 0, // 不返回_id字段
                                activity_category: 1, // 返回activity_category字段
                            }
                        }
                    ]
                }
            },
            {//通过以下方法,将actInfo中的内容提取出来,放到记录的根节点
                $replaceRoot: { newRoot: { $mergeObjects: [{ $arrayElemAt: ["$actInfo", 0] }, "$$ROOT"] } }
            },
            {
                $lookup: {// 获取项目大类信息
                    from: "itemcategories",
                    localField: "itemCategoryInfo",
                    foreignField: "_id",
                    as: "itCategoryInfo",
                    pipeline: [
                        {
                            $project: {
                                _id: 0, // 不返回_id字段
                                item_category: 1, // 返回item_category字段
                            }
                        }
                    ]
                }
            },
             {//通过以下方法,将itCategoryInfo中的内容提取出来,放到记录的根节点
                $replaceRoot: { newRoot: { $mergeObjects: [{ $arrayElemAt: ["$itCategoryInfo", 0] }, "$$ROOT"] } }
            },
            {
                $lookup: {// 获取项目信息
                    from: "items",
                    localField: "itemInfo",
                    foreignField: "_id",
                    as: "itmInfo",
                    pipeline: [
                        {
                            $project: {
                                _id: 0, // 不返回_id字段
                                item_name: 1, // 返回item_name字段
                                item_demand: 1,
                                item_evidence: 1,
                                item_mark: 1
                            }
                        }
                    ]
                }
            },
            {//通过以下方法,将itmInfo中的内容提取出来,放到记录的根节点
                $replaceRoot: { newRoot: { $mergeObjects: [{ $arrayElemAt: ["$itmInfo", 0] }, "$$ROOT"] } }
            },
            {
                $lookup: {// 获取项目积分信息
                    from: "itempoints",
                    localField: "itemPointsInfo",
                    foreignField: "_id",
                    as: "itemptsInfo",
                    pipeline: [
                        {
                            $project: {
                                _id: 0, // 不返回_id字段
                                item_points_name: 1, // 返回item_name字段
                                item_points_value: 1,
                                item_points_unit: 1,
                                item_mark: 1
                            }
                        }
                    ]
                }
            },

            {//通过以下方法,将itemptsInfo中的内容提取出来,放到记录的根节点
                $replaceRoot: { newRoot: { $mergeObjects: [{ $arrayElemAt: ["$itemptsInfo", 0] }, "$$ROOT"] } }
            },
            { // 通过以上方法,从college_name majInfo等中提取出了字段并放在了根节点,此时college_name majInfo等就不需要了,以下可屏蔽college_name等
                $project: {
                    stuInfo:0,
                    itemptsInfo: 0,
                    actInfo: 0,
                    itmInfo: 0,
                    itCategoryInfo:0,
                    _id: 0,
                    __v: 0,
                    password: 0,
                    points: 0,
                    year: 0,
                    role: 0
                }
            },
            {// 查询条件
                $match: searchData
            },
            {// 通过$facet,我们可以获得分页数据和总记录数,$facet相当于创建独立的管道
                // 如下:创建了两个独立管道分别为countarr和data1,分别执行自己的运算并返回结果
                $facet: {
                    //countarr管道,最终返回的结果存放在countarr数组中,格式为 countarr:[{totalRecords:7}]
                    "countarr": [
                        { $count: "totalRecords" }// 使用$count操作符计算符合条件的记录数量,并将结果放在一个名为”totalRecords”的字段中
                    ],
                    // data1管道
                    "data1": [
                        {
                            $skip: (page - 1) * pagesize
                        },
                        {
                            $limit: pagesize
                        },
                        {
                            $sort: { "_id": 1 }
                        }
                    ]
                }
            },
            {
                $project: {
                    // 从countarr:[{totalRecords:7}]数组中,提取下标为0的数据,赋值给total
                    total: { $arrayElemAt: ["$countarr.totalRecords", 0] },
                    // 正常返回数据
                    records: "$data1"
                }
            }

        ])

        // 返回结果
        res.status(200).send({
            code: 200,
            data: result,
            msg: 'success'
        })
    } catch (error) {
        console.log('错误信息:', error)
        res.status(400).send({
            code: 400,
            msg: '服务器错误'
        })
    }
})

;