使用TypeORM QueryBuilder对JSONB数组对象的vin_code执行ILIKE查询
实现JSONB字段中数组元素的ILIKE模糊查询
问题原因
你之前的写法无法生效,核心问题有两个:
@>是PostgreSQL JSONB的精确包含匹配操作符,只能检查JSON结构是否完全包含指定内容,不支持模糊匹配逻辑。- 你将
ILike()函数直接序列化到JSON字符串中,数据库收到的只是普通字符串(比如"vin_code": "ILike('MR0KX8CD301906222')"),无法识别为SQL模糊匹配操作。
解决方案(基于PostgreSQL + TypeORM)
要实现JSON数组中vin_code的ILIKE模糊查询,需要先将JSON数组展开为行,再对每个元素的vin_code字段做匹配。以下是两种常用写法:
方法1:使用EXISTS子查询(推荐,避免重复行)
const targetVin = "MR0KX8CD301906222"; // 可替换为动态值 qb.orWhere(`EXISTS ( SELECT 1 FROM jsonb_array_elements(task.client_data->'searchData'->'cars'->'new') AS car_item WHERE car_item->>'vin_code' ILIKE :vinPattern )`, { vinPattern: `%${targetVin}%` });
方法2:使用JOIN展开数组(需注意去重)
如果需要同时返回匹配的数组元素,可以用JOIN展开,否则记得加distinct()避免重复结果:
const targetVin = "MR0KX8CD301906222"; qb.leftJoinAndSelect( "jsonb_array_elements(task.client_data->'searchData'->'cars'->'new')", "car_item" ) .orWhere("car_item->>'vin_code' ILIKE :vinPattern", { vinPattern: `%${targetVin}%` }) .distinct(true); // 去重,避免同一task因多个匹配vin返回多行
代码说明
jsonb_array_elements():PostgreSQL函数,将JSON数组展开为多行记录,每个数组元素对应一行。->>:JSONB操作符,将指定JSON字段的值转为文本类型,这样才能用ILIKE做模糊匹配。ILIKE:PostgreSQL的大小写不敏感模糊匹配,若需要大小写敏感,替换为LIKE即可。
内容的提问来源于stack exchange,提问作者Yelaman Uisunbayev
相关产品推荐
相关产品推荐

