Nestjs typeorm 一对多关系, 取多的一方的最新一条记录进行排序

我们常常有这样的要求, 一篇文章, 里面有一个一对多的关联关系记录. 如果我们要在一个列表里, 对多篇文章, 以最新的一条记录做排序.

打个例子, 一项目, 多人同时开发, 每次推送, 都添加一条信息. 要做列表展示时, 只显示每个人的最近一条记录.

js 复制代码
// 项目
@Entity("project")
export class Project {
    @Column()
    id: number;
    
    @CreateDateColumn({ comment: "创建时间", name: 'create_at', nullable: true })
    createAt?: Date
    
    // 一对多的关系
    @OneToMany(() => Process, process => process.component)
    processes: Process[];
    
    // 最新的一条进展, 映射使用
    newestProcess?: Process;
}

// 添加进展记录
@Entity("process")
export class Process {
    @Column()
    id: number;
    
    @CreateDateColumn({ comment: "创建时间", name: 'create_at', nullable: true })
    createAt?: Date
    
    // 多对一的关系
    @ManyToOne(() => Project, project => project.processes)
    @JoinColumn({name : "project_id"})
    project: Project;
    
}

一般操作, 不以 processes 做排序的情况可做.

上面二个表, 直接关联查找出所以有的数据, processes 数组查出来后, 在计算最新一条, 通过模型转换成需要的列表.

js 复制代码
const result = await this.componentRepo.createQueryBuilder('project')
        .leftJoinAndSelect('project.processes', 'processes')
        .getMany()

得到 result 后, 我们在对 processes 去排序, 取得最新一条. 但是, 这里有个问题, 不能用 process 的 createAt 去排序, 数据会不准

优秀操作, 可以对 processes 里面字段做排序

同样的操作, 多了一步映射一条数据. 把 processes 最新的一条映射到外面 Project 去

在实体表 Project 添加上

js 复制代码
// 最新的一条进展, 映射使用
newestProcess?: Process;

然后,

js 复制代码
const result = await this.componentRepo.createQueryBuilder('project')
        .leftJoin('project.processes', 'processes') // 不需要全部数据, 可以用 leftJoin
        .leftJoinAndMapOne('project.newestProcess', Process, 'newestProcess', 'newestProcess.create_at = (SELECT MAX(p.create_at) FROM processes p WHERE p.projectt_id = project.id)') // 映射最新一条进展
        .orderBy("newestProcess.createAt", "DESC") // 这里排序
        .getMany()

上面 leftJoinAndMapOne 条件的原理是, 查到 processes 里面 create_at 时间是最大的一条记录, 然后给到 newestProcess.create_at.

PS: 就这一条映射, typeorm 官方文档真没有啊, 翻了几遍内外网, 都没有找到方法, 我一开始是第一种方法来做的, 后面发现排序有问题, 一直找解决方法都没有找到, 最后查看源码, 发现 leftJoinAndMapOne 可以上 sql 原始语法, 后面 sql 的原始语法来做了. 尝试了不知道多少次了, 一次次改 sql, 出错了也不显示, 一次次请求数据, 最后成功了, 感慨万千啊.

相关推荐
牛马喜喜1 小时前
如何优雅使用node.js操作数据库 助力个人应用开发
后端·orm
Mintopia2 小时前
Node.js 中 child_process 模块:子进程的创建与运用
前端·javascript·node.js
Mintopia3 小时前
深入理解 Node.js 的事件驱动机制
前端·javascript·node.js
whltaoin3 小时前
Node.js v22.14.0 多平台安装指南:Windows、Linux 和 macOS 详细教程
node.js
Kagol4 小时前
TinyPro 后台管理系统从启动 ➡️ 使用 ➡️ 二开,看这一篇就够了!点赞、收藏⭐,不迷路!
前端·vue.js·nestjs
还是鼠鼠7 小时前
Node.js自定义中间件
javascript·vscode·中间件·node.js·json·express
橘右溪1 天前
Node.js核心模块及Api详解
node.js
在下千玦2 天前
#管理Node.js的多个版本
node.js
你的人类朋友2 天前
MQTT协议是用来做什么的?此协议常用的概念有哪些?
javascript·后端·node.js
还是鼠鼠2 天前
Node.js中间件的5个注意事项
javascript·vscode·中间件·node.js·json·express