如何用TypeORM单查询获取含最新帖子的用户列表(NestJS+MySQL)
获取带有最新单条帖子的用户列表(TypeORM解决方案)
问题背景
使用Nest.js + TypeORM + MySQL技术栈,实体定义如下:
@Entity() export class User { @PrimaryGeneratedColumn('uuid') id: string @Column() name: string @OneToMany(() => Post, post => post.user) posts: Post[] } @Entity() export class Post { @PrimaryGeneratedColumn('uuid') id: string @Column() title: string @ManyToOne(() => User, user => user.posts) user: User @CreateDateColumn() created_at: Date }
尝试通过以下查询获取每个用户的最新单条帖子,但查询未按帖子created_at倒序筛选出最新帖子:
import { getRepository } from 'typeorm'; import { User } from './entities/User'; import { Post } from './entities/Post'; const usersWithPosts = await getRepository(User) .createQueryBuilder('user') .leftJoinAndMapOne( 'user.post', // Map the 'post' property of the 'user' entity Post, // Target entity 'post', // Alias for the 'post' entity 'user.id = post.userId', // ON condition for the join qb => qb.orderBy('post.created_at', 'DESC') // Order posts here ) .orderBy('user.name', 'ASC') // Order users here .getMany();
需要仅使用TypeORM查询(不使用原生SQL)实现需求。
解决方案
方法一:子查询排序后限制返回数量
leftJoinAndMapOne需要明确限制子查询返回单条记录,仅排序无法确保只取最新帖子。修改后代码如下:
const usersWithPosts = await getRepository(User) .createQueryBuilder('user') .leftJoinAndMapOne( 'user.latestPost', // 映射到用户的新属性latestPost (subQuery) => subQuery .select('post.*') .from(Post, 'post') .where('post.userId = user.id') .orderBy('post.created_at', 'DESC') .limit(1), // 仅取最新的一条帖子 'latestPost', 'user.id = latestPost.userId' ) .orderBy('user.name', 'ASC') .getMany();
方法二:通过子查询匹配最新创建时间
若需避免同一时间多条帖子的歧义,可先查询每个用户帖子的最新创建时间,再关联匹配对应帖子:
const usersWithPosts = await getRepository(User) .createQueryBuilder('user') .leftJoinAndMapOne( 'user.latestPost', Post, 'latestPost', `latestPost.userId = user.id AND latestPost.created_at = ( SELECT MAX(p.created_at) FROM post p WHERE p.userId = user.id )` ) .orderBy('user.name', 'ASC') .getMany();
注意事项
- 需在
User实体中临时添加latestPost?: Post属性,用于映射查询结果; - 方法一更简洁高效,适合绝大多数场景;方法二在存在同一时间多条帖子时,会返回该时间点的任意一条(若需全部返回,可改用
leftJoinAndMapMany)。
内容的提问来源于stack exchange,提问作者Lalit Kumar
相关产品推荐
相关产品推荐

