Mikro ORM:如何按JSON字段中对应数据类型进行排序?
解决Mikro ORM JSON嵌入式字段排序及类型识别问题
问题分析
使用@Embedded定义JSON类型的嵌套元数据字段时,直接通过orderBy: { meta: { bar: 'asc' } }排序会触发ORM内部路径解析错误;而普通JSON字段排序默认按字符串处理,是因为数据库对JSON字段的取值默认返回字符串类型,未做类型转换。
解决方案
1. 修复排序报错并实现按数值类型排序
放弃嵌套的orderBy写法,改用数据库原生的JSON路径表达式结合类型转换,直接指定排序逻辑:
方式一:使用QueryBuilder(推荐,更灵活)
const users = await em.createQueryBuilder(User) // 针对PostgreSQL,用->>获取字符串值后转int类型,再排序 .orderBy('(meta->>\'bar\')::int', 'asc') .getResult();
方式二:在em.find中使用原生表达式
const users = await em.find(User, {}, { orderBy: { // 直接写原生SQL的排序表达式 '(meta->>\'bar\')::int': 'asc' } });
2. 让ORM识别JSON字段内的数据类型
如果希望ORM在查询时更贴合JSON字段内的类型,可通过以下方式优化:
- 将JSON字段类型改为
jsonb(PostgreSQL推荐,支持更高效的类型操作和索引),在实体定义中指定:@Embedded(() => Meta, { object: true, nullable: true, type: 'jsonb' }) meta?: Meta - 若需全局统一处理类型,可自定义类型转换器为
Meta类的bar字段指定类型转换规则,但这种方式复杂度较高,一般推荐查询时显式转换更直接。
关键说明
PostgreSQL中,->>操作符会将JSON字段的取值转为字符串,->操作符返回JSON原生类型;若要按数值排序,必须显式将字符串转为int或numeric类型,否则数据库会按字符串字典序排序,导致结果不符合预期。
内容的提问来源于stack exchange,提问作者plusheen
相关产品推荐
相关产品推荐

