为了账号安全,请及时绑定邮箱和手机立即绑定

typeorm 按上次 createdAt 选择 OneToMany 实体

typeorm 按上次 createdAt 选择 OneToMany 实体

小怪兽爱吃肉 2021-11-25 19:47:19
我认为有一个非常典型的问题 -OneToMany通过 typeorm选择关系的最新实体的正确方法是什么?数据库是postgresql@Entity('hubs')export class Hub {    @PrimaryGeneratedColumn('uuid')    id: string;    @Column()    ip: string;    @OneToMany(type => HubStatus, statusLog => statusLog.hub, { cascade: true })    statusLog: Array<HubStatus>;    @UpdateDateColumn()    updatedAt: Date;    lastStatus: any;    @AfterLoad()    async getStatus() {          const query = createQueryBuilder(Hub)            .leftJoinAndSelect("Hub.statusLog", "statusLog", 'Hub.id = :id', { id: this.id })            //.addSelect("MAX(statusLog.createdAt)")            //.andHaving('statusLog.createdAt = MAX(statusLog.createdAt)');            //.andWhere('Hub.id = :id', { id: this.id })            //.andWhere('statusLog.createdAt = MAX(statusLog.createdAt)');          //assign part of result to this.lastStatus    }}@Entity('hub-status')export class HubStatus {    @PrimaryGeneratedColumn()    id: string;    @Column({type: 'json')    somecolumn    @ManyToOne(type => Hub, hub => hub.statusLog)    hub: Hub;    @CreateDateColumn()    createdAt: Date;}我想获得相关的最新(通过createdAt)HubStatus的@AfterLoad块。max不能在where子句中使用,我也尝试了使用maxin 的多种选项,select但由于不同的原因它们失败了。
查看完整描述

2 回答

?
绝地无双

TA贡献1946条经验 获得超4个赞

我是这样做的,所以它至少可以用于开发目的:


@AfterLoad()

async getStatus() {

    const innerSelect = getRepository(HubStatus)

        .createQueryBuilder()

        .select('id')

        .where('HubStatus.hub.id = :id')

        .orderBy('id', "DESC")

        .limit(1);


    const query = createQueryBuilder(Hub)

        .select('somecolumn')

        .leftJoin(`Hub.statusLog`, "statusLog", `statusLog.id = (${innerSelect.getSql()})`, { id: this.id })


    this.lastStatus = (await query.getRawOne()).somecolumn;

}

但问题仍然存在 - 可能会有数百万个条目HubStatus,如果认为ORDER BY+LIMIT 1解决方案在这种情况下不会表现良好。


查看完整回答
反对 回复 2021-11-25
?
慕妹3242003

TA贡献1824条经验 获得超6个赞

另一种方法是在连接条件中使用leftJoinAndMapOne查询构建器方法和NOT EXISTSSQL 条件来测试以后的实体:


      const query = createQueryBuilder(Hub)

        .leftJoinAndMapOne('Hub.statusLog', HubStatus, 'statusLog',

         `Hub.id = statusLog.hubId AND NOT EXISTS (

         SELECT 1 FROM hub-status hs1 WHERE hs1.hubId = Hub.id AND hs1.id > statusLog.id)`,

        ).getMany()


查看完整回答
反对 回复 2021-11-25
  • 2 回答
  • 0 关注
  • 250 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信