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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 17:57:08