如何在MikroORM中按嵌套实体Entity3的最大updatedAt排序查询Entity1
在MikroORM中按嵌套Entity3的updatedAt排序Entity1的findAndCount查询
首先,你需要通过关联查询将Entity2和Entity3纳入查询上下文,再基于Entity3的updatedAt字段对Entity1排序。由于是一对多嵌套关系,单个Entity1可能对应多个Entity3,通常取每个Entity1关联的Entity3中最新的updatedAt值作为排序依据。
实体定义参考(简化版)
@Entity() export class Entity1 { @PrimaryKey() id!: number; @OneToMany(() => Entity2, entity2 => entity2.entity1) entity2s = new Collection<Entity2>(this); } @Entity() export class Entity2 { @PrimaryKey() id!: number; @ManyToOne(() => Entity1) entity1!: Entity1; @OneToMany(() => Entity3, entity3 => entity3.entity2) entity3s = new Collection<Entity3>(this); } @Entity() export class Entity3 { @PrimaryKey() id!: number; @ManyToOne(() => Entity2) entity2!: Entity2; @Property() updatedAt!: Date; }
核心查询写法
const [entities, count] = await orm.em.findAndCount(Entity1, {}, { // 关联加载嵌套实体,确保能访问到Entity3的字段 populate: ['entity2s.entity3s'], // 用子查询获取每个Entity1对应的最新Entity3的updatedAt,以此作为排序键 orderBy: { $expr: (qb) => qb.select('MAX(e3.updatedAt)') .from(Entity3, 'e3') .innerJoin('e3.entity2', 'e2') .where('e2.entity1.id = entity1.id'), }, // 指定排序方向:DESC为倒序(最新的在前),ASC为升序 orderByDirection: 'DESC', });
关键说明
- 关联加载 vs 仅关联表:如果不需要返回Entity2和Entity3的具体数据,可替换
populate为join,仅关联表而不加载数据:join: { entity2s: { entity3s: true, }, }, - 避免重复记录:子查询方式能确保每个Entity1只返回一次,直接关联排序会因一对多关系产生重复的Entity1条目。
- 分组排序替代方案:也可通过左连接+分组实现相同效果:
const [entities, count] = await orm.em.findAndCount(Entity1, {}, { join: { leftJoinAndSelect: { e2: 'entity1.entity2s', e3: 'e2.entity3s', }, }, groupBy: ['entity1.id'], orderBy: { 'MAX(e3.updatedAt)': 'DESC', }, });
内容的提问来源于stack exchange,提问作者vicebas
相关产品推荐
相关产品推荐

