You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Prisma嵌套属性排序报错:如何按角色名称字母序排序用户?

按用户角色名称排序Prisma查询的问题与解决

我用Prisma和TypeScript开发,需要按用户的角色名称字母序对用户列表排序,但执行findMany时控制台报错:

Argument user_roles: Got invalid value 'asc' on prisma.findManymme_user. Provided String, expected mme_user_roleOrderByRelationAggregateInput:
type mme_user_roleOrderByRelationAggregateInput {
_count?: SortOrder
}

试过用_count排序,但需求是按角色名称字母序排序,下面是我的实现代码和Prisma Schema:

实现代码

export async function getUser({ skip, limit, pageSize, search, sortBy }: { skip: number, limit: number, pageSize: number, search: string, sortBy: { id: string, desc: boolean }[] }): Promise<any> {
    const sorting: { [key: string]: string }[] = sortBy.length > 0 ? sortBy.map((sort: any) => {
        if (sort.id.includes('.')){
            const idArr = sort.id.split('.')
            let nestedSort: any = { [idArr[idArr.length-1]]: sort.desc ? 'desc' : 'asc' }
            idArr.reverse().forEach((id: string, index: number) => {
                if(index > 0){
                    nestedSort = { [id]: nestedSort }
                }
            })
            return nestedSort
        }
        return { [sort.id]: sort.desc ? 'desc' : 'asc' }
    }) : [{ userid: 'asc' }]

    console.log('sorting', JSON.stringify(sorting, null, 2));
    console.log('sortby', JSON.stringify(sortBy, null, 2));

    const filter = [
        {
            userid: {
                contains: search
            },
        },
        {
            nama: {
                contains: search
            },
        },
        {
            role: {
                contains: search
            },
        },
        {
            email: {
                contains: search
            },
        },
    ]

    return prisma.mme_user.findMany({
        skip,
        take: Number(pageSize) < Number(limit) ? Number(pageSize) : Number(limit),
        include: {
          user_roles: {
              include: {
                  role: true
              }
          }
        },
        
        where: {
            is_deleted: 0,
            OR: filter
        },
        orderBy: sorting
    })
}

Prisma Schema

model mme_role {
  id         Int             @id @default(autoincrement())
  name       String          @unique @db.VarChar(255)
  privileges mme_privilege[]
  user_roles mme_user_role[]
}

model mme_user_role {
  id      Int      @id @default(autoincrement())
  user_id Int
  user    mme_user @relation(fields: [user_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
  role_id Int
  role    mme_role @relation(fields: [role_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
}

model mme_user {
  id                 Int                      @id @default(autoincrement())
  userid             String                   @unique(map: "idxUser") @db.VarChar(25)
  passwd             String                   @db.VarChar(250)
  nama               String                   @db.VarChar(50)
  role               String                   @db.VarChar(15)
  email              String                   @db.VarChar(250)
  created_at         DateTime                 @db.DateTime(0)
  last_updated       DateTime                 @db.DateTime(0)
  is_deleted         Int                      @default(0) @db.UnsignedTinyInt
  deleted_at         DateTime?                @db.DateTime(0)
  logged_in          Int                      @default(0) @db.UnsignedTinyInt
  activities         mme_activity[]
  notifications      mme_notification[]
  product_price_list mme_product_price_list[]
  user_roles         mme_user_role[]

  @@index([is_deleted], map: "mme_user_is_deleted")
}

问题原因

报错是因为直接对多对多关联字段user_roles用asc/desc排序不合法,Prisma只允许对关联字段用_count统计排序。要按角色名称排序,必须通过关联的role模型的name字段来实现,同时要注意:一个用户可能关联多个角色,需明确排序逻辑。

解决方法

方式1:按用户关联的第一个角色名称排序

修改排序逻辑,针对user_roles.role.name字段生成正确的排序配置:

const sorting: { [key: string]: any }[] = sortBy.length > 0 ? sortBy.map((sort: any) => {
    // 专门处理角色名称排序的情况
    if (sort.id === 'user_roles.role.name') {
        return {
            user_roles: {
                role: {
                    name: sort.desc ? 'desc' : 'asc'
                }
            }
        }
    }
    // 其他字段的原有逻辑保持不变
    if (sort.id.includes('.')){
        const idArr = sort.id.split('.')
        let nestedSort: any = { [idArr[idArr.length-1]]: sort.desc ? 'desc' : 'asc' }
        idArr.reverse().forEach((id: string, index: number) => {
            if(index > 0){
                nestedSort = { [id]: nestedSort }
            }
        })
        return nestedSort
    }
    return { [sort.id]: sort.desc ? 'desc' : 'asc' }
}) : [{ userid: 'asc' }]

方式2:按用户关联角色名称的极值排序(多角色场景)

如果用户有多个角色,可按角色名称的最小/最大值排序,确保排序逻辑明确:

// 示例:按用户关联角色名称的最小值升序排序
return prisma.mme_user.findMany({
    skip,
    take: Number(pageSize) < Number(limit) ? Number(pageSize) : Number(limit),
    include: {
      user_roles: {
          include: {
              role: true
          }
      }
    },
    where: {
        is_deleted: 0,
        OR: filter
    },
    orderBy: [
        {
            user_roles: {
                _min: {
                    role: {
                        name: 'asc'
                    }
                }
            }
        }
    ]
})

注意事项

  • 确保前端传递的排序字段标识sort.id为user_roles.role.name,与后端逻辑匹配
  • 多角色场景下,必须明确排序规则,避免结果不符合预期

内容的提问来源于stack exchange,提问作者Aryagara Kristandy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 18:46:03