Typeorm 查询构建器加入最新行

use*_*304 0 node.js typescript typeorm nestjs

我正在使用带有 TypeORM 的 NestJS

我得到了两个具有关系的实体:

export class Device {
    @PrimaryGeneratedColumn()
    id: number;

    @Column("macaddr")
    mac: string;

    @OneToMany(type => DeviceStatus, deviceStatus => deviceStatus.mac)
    @JoinColumn()
    status: DeviceStatus[]

    @Column()
    created: Date;
}

export class DeviceStatus {
    @PrimaryGeneratedColumn()
    id: number;

    @ManyToOne(type => Device, device => device.mac)
    @JoinColumn({ name: "mac", referencedColumnName: "mac" })
    mac: Device;

    @Column()
    deviceState: number;

    @Column()
    created: Date;
}
Run Code Online (Sandbox Code Playgroud)

我想获取 Device 但只有它的status属性是最新的 DeviceStatus 。

现在我这样做:

const deviceQuery: Device = await this.deviceRepository
                        .createQueryBuilder("device")
                        .where('device.id = :id AND "device"."userId" = :user', {id: id, user: user.id})
                        .getOne();


const statusQuery: DeviceStatus = await this.deviceStatusRepository.createQueryBuilder("status")
                        .where('status.mac = :mac', { mac: deviceQuery.mac })
                        .orderBy('created', "DESC")
                        .limit(1)
                        .getOne();

deviceQuery.status = [statusQuery];
Run Code Online (Sandbox Code Playgroud)

如何仅使用一个 typeorm queryBuilder 查询来做到这一点?

我已经尝试过这个,但它没有将status属性映射到设备,.execute()获取所有 DeviceStatus 属性但它不会映射实体。

const deviceQuery: Device = await this.deviceRepository
                    .createQueryBuilder("device")
                    .leftJoinAndSelect(subquery => {
                        return subquery
                            .from(DeviceStatus, "status")
                            .innerJoin(subquery => {
                                return subquery
                                    .select(["status2.mac"])
                                    .addSelect("MAX(created)", "lastdate")
                                    .from(DeviceStatus, "status2")
                                    .groupBy("status2.mac")
                            }, "status3", 'status.created = "status3"."lastdate"')
                    }, "status", 'device.mac = "status"."mac"')
                    .where('device.id = :id AND "device"."userId" = :user', {id: id, user: user.id})
                    .getOne();
Run Code Online (Sandbox Code Playgroud)

Jor*_*ane 5

您可以通过加入 status 2 次来实现此目的。第二个状态连接 ( next_status) 条件应该比较created日期并在第一个连接状态之后。然后检查是否next_status为空,这意味着没有比第一次加入更年轻的状态

代码可能是更好的解释:

const device: Device = await this.deviceRepository
                    .createQueryBuilder("device")
                    .leftJoinAndSelect("device.status", "status")
                    .leftJoin("device.status", "next_status", "status.created < next_status.created")
                    .where("next_status.id IS NULL")

// device.status is the latest status
Run Code Online (Sandbox Code Playgroud)