Prisma后端GET接口多可选排序问题:仅首个orderBy项生效
问题分析
你的代码里第二个排序规则不生效,核心原因有两个:
- 当前仅支持单个排序参数(比如
id_desc或createdAt_asc),无法同时指定两个字段的排序逻辑,另一个字段始终用默认的asc;且orderBy数组中createdAt排在首位,只有当多条任务的createdAt完全相同时,才会触发id的排序,所以看起来第二个规则没效果。 - 未提前判断
sortQuery是否存在就执行split,如果请求不带sort参数会直接报错。
解决方案
以下提供两种实现方案,根据你的需求选择:
方案一:支持多排序规则(推荐)
允许通过逗号分隔传入多个排序规则(比如sort=createdAt_desc,id_asc),解析后生成对应排序数组:
router.get("/tasks", async (req, res) => { const currentPage = parseInt(req.query.page) || 1; const listPerPage = 45; const offset = (currentPage - 1) * listPerPage; const category = req.query.category; const sortQuery = req.query.sort; // 默认排序:createdAt升序 → id升序 let orderBy = [ { createdAt: "asc" }, { id: "asc" } ]; if (sortQuery) { // 拆分多个排序规则,过滤非法字段 const sortRules = sortQuery.split(",").map(rule => { const [field, direction] = rule.split("_"); if (["createdAt", "id"].includes(field)) { return { [field]: direction || "asc" }; } return null; }).filter(Boolean); // 若解析后无合法规则,恢复默认 if (sortRules.length) { orderBy = sortRules; } } const allTasks = await prisma.task.findMany({ orderBy, where: category ? { category } : {}, // 处理category为空的情况 skip: offset, take: listPerPage, }); res.json({ data: allTasks, meta: { page: currentPage }, }); });
方案二:单一参数切换排序优先级
保持单个sort参数,但根据传入字段调整排序优先级:
router.get("/tasks", async (req, res) => { const currentPage = parseInt(req.query.page) || 1; const listPerPage = 45; const offset = (currentPage - 1) * listPerPage; const category = req.query.category; const sortQuery = req.query.sort; let idSortBy = "asc"; let dateSortBy = "asc"; let orderBy = [ { createdAt: dateSortBy }, { id: idSortBy } ]; if (sortQuery) { const [field, direction] = sortQuery.split("_"); if (field === "id") { idSortBy = direction || "asc"; // 将id设为第一排序位 orderBy = [{ id: idSortBy }, { createdAt: dateSortBy }]; } else if (field === "createdAt") { dateSortBy = direction || "asc"; orderBy = [{ createdAt: dateSortBy }, { id: idSortBy }]; } } const allTasks = await prisma.task.findMany({ orderBy, where: category ? { category } : {}, skip: offset, take: listPerPage, }); res.json({ data: allTasks, meta: { page: currentPage }, }); });
额外注意事项
- 必须将
currentPage转为数字,避免字符串参与计算导致错误; - 处理
category为空的场景,防止where条件出现undefined引发查询异常; - 对排序字段做白名单校验,避免传入非法字段导致Prisma报错。
内容的提问来源于stack exchange,提问作者Craws
相关产品推荐
相关产品推荐

