PostgreSQL数组枚举查询报错及NestJS数据库类型配置咨询
PostgreSQL数组枚举字段筛选错误及NestJS配置方案
错误场景
执行SQL查询时触发以下错误:
Pgadmin sql malformed array literal - No operator matches the given name and argument type(s). You might need to add explicit type casts
对应的SQL语句:
SELECT COUNT(DISTINCT("c"."id")) AS "cnt" FROM "company" "c" LEFT JOIN "company_participants" "p" ON "p"."company_id"="c"."id" LEFT JOIN "company_step" "cs" ON "cs"."id"="c"."current_step_id" LEFT JOIN "brand" "brand" ON "brand"."id"="c"."brand_id" LEFT JOIN "user" "projectLead" ON "projectLead"."id"="c"."project_lead_id" WHERE "p"."user_id" = 126 AND "c"."project_type" IN (1,2)
NestJS Query Builder代码:
qb = this.createQueryBuilder('c') .leftJoinAndSelect('c.participants', 'p') .where('p.userId = :id', { id: requestOwner.id }) .select(['c', 'cs.name', 'cs.id', 'user', 'c.createdBy']) .leftJoin('c.currentStep', 'cs') .leftJoinAndSelect('c.brand', 'brand') .leftJoinAndSelect('c.projectLead', 'projectLead');
实体类中projectType定义:
@Column({ type: 'enum', enum: ProjectTypeEnum, array: true, nullable: true, }) projectType: ProjectTypeEnum[];
PostgreSQL中该字段类型为campaign_project_type_enum[],默认值为'{4}'::campaign_project_type_enum[],需为该字段添加筛选和分页功能。
错误原因
project_type是数组类型的枚举字段,SQL中使用普通的IN (1,2)语法不匹配PostgreSQL数组枚举的操作规则,必须使用数组专属操作符(如ANY、&&)并保证参数类型与枚举数组一致。
解决步骤
1. 修改Query Builder实现正确筛选
针对数组枚举字段,有两种常用筛选方式:
- 方式一:匹配数组中包含任一指定枚举值
// 假设ProjectTypeEnum中1对应TYPE1,2对应TYPE2 const targetTypes = [ProjectTypeEnum.TYPE1, ProjectTypeEnum.TYPE2]; qb = this.createQueryBuilder('c') .leftJoinAndSelect('c.participants', 'p') .where('p.userId = :id', { id: requestOwner.id }) // 筛选数组中包含任一目标类型 .andWhere(':type = ANY(c.projectType)', { type: ProjectTypeEnum.TYPE1 }) .orWhere(':type = ANY(c.projectType)', { type: ProjectTypeEnum.TYPE2 }) .select(['c', 'cs.name', 'cs.id', 'c.createdBy']) .leftJoin('c.currentStep', 'cs') .leftJoinAndSelect('c.brand', 'brand') .leftJoinAndSelect('c.projectLead', 'projectLead');
- 方式二:用数组交集操作符(更简洁,适用于多值筛选)
qb = this.createQueryBuilder('c') // ... 其他关联和条件 .andWhere('c.projectType && :targetTypes', { targetTypes });
2. 修正Schema配置
原配置中items类型为string,需改为枚举类型以匹配数据库字段:
const arraySchemaOptions = { type: 'array', items: { type: 'enum', enum: ProjectTypeEnum, // 关联你的枚举定义 }, };
如果使用class-validator做参数校验,还需添加对应装饰器确保输入合法:
import { IsArray, IsEnum } from 'class-validator'; export class FilterDto { @IsArray() @IsEnum(ProjectTypeEnum, { each: true }) projectTypes: ProjectTypeEnum[]; }
3. 添加分页功能
在Query Builder中通过skip()和take()实现分页:
// 从请求参数获取分页参数,默认第一页、每页10条 const page = parseInt(req.query.page) || 1; const pageSize = parseInt(req.query.pageSize) || 10; // 添加分页逻辑 qb.skip((page - 1) * pageSize) .take(pageSize); // 如需返回总数,单独执行count查询 const totalCount = await qb.getCount(); const data = await qb.getMany(); return { data, totalCount, page, pageSize };
内容的提问来源于stack exchange,提问作者userrj_vj_051620
相关产品推荐
相关产品推荐

