如何使用TypeORM查询每个文档类别下的最新一条记录
这个需求完全可以仅通过TypeORM实现,不需要额外的内存数据处理,以下是两种常用实现方案:
方案1:全数据库兼容方案(适配MySQL、PostgreSQL、SQLite等绝大多数数据库)
核心逻辑是先通过子查询查出每个type分类下的最大created_at时间,再关联原表匹配出对应记录,示例代码如下:
import { getRepository } from 'typeorm'; import { UserDocument } from './你的实体文件路径'; async function getLatestDocumentPerType(userId: number) { const documentRepository = getRepository(UserDocument); // 子查询:统计每个文档类型对应的最新创建时间 const maxCreatedSubQuery = documentRepository .createQueryBuilder('subDoc') .select('subDoc.type', 'type') .addSelect('MAX(subDoc.created_at)', 'latest_created_at') .where('subDoc.user_id = :userId', { userId }) .groupBy('subDoc.type'); // 主查询:关联子查询匹配对应完整记录 return documentRepository .createQueryBuilder('doc') .innerJoin( `(${maxCreatedSubQuery.getQuery()})`, 'latestDoc', 'doc.type = latestDoc.type AND doc.created_at = latestDoc.latest_created_at' ) .where('doc.user_id = :userId', { userId }) // 同步子查询的参数 .setParameters(maxCreatedSubQuery.getParameters()) .getMany(); }
调用getLatestDocumentPerType(21)返回的结果和你示例预期完全匹配:PERSONAL DOCUMENTS分类返回id为245的最新记录,EMPLOYEE DOCUMENTS返回id为244的记录,EDUCATIONAL DOCUMENTS返回id为246的记录。
方案2:PostgreSQL专属精简方案
如果你使用的是PostgreSQL数据库,可以借助DISTINCT ON语法实现更简洁、性能更高的查询:
async function getLatestDocumentPerTypePG(userId: number) { const documentRepository = getRepository(UserDocument); return documentRepository .createQueryBuilder('doc') .select('DISTINCT ON (doc.type) doc.*') .where('doc.user_id = :userId', { userId }) // 先按type分组,同组内按创建时间倒序,DISTINCT ON会自动取每组第一条 .orderBy('doc.type, doc.created_at DESC') .getRawMany(); }
注意事项
如果同一分类下存在多条created_at完全相同的记录,上述查询会返回所有匹配的记录,你可以在排序规则中追加按id倒序的规则,保证每个分类仅返回一条记录:orderBy('doc.type, doc.created_at DESC, doc.id DESC')。
你也可以根据业务需求追加其他筛选条件,比如按tenant_id过滤,直接在where条件中添加对应规则即可。
内容的提问来源于stack exchange,提问作者xxoyx
相关产品推荐
相关产品推荐

