基于TypeORM与NestJS,根据双用户ID查找聊天会话
高效查找包含指定两个用户的聊天会话(NestJS + TypeORM)
当前实现先查询包含其中一个用户的所有聊天,再在内存中过滤同时包含另一个用户的会话,当数据量较大时性能极差——不仅会加载大量无关数据到内存,还无法利用数据库索引做优化。
以下是两种更高效的实现方案,直接在数据库层面完成过滤:
方案一:基础查询(仅返回ChatEntity)
利用QueryBuilder关联用户表,通过分组统计筛选出同时包含两个用户的聊天:
const chat = await this.chatRepository .createQueryBuilder('chat') // 关联聊天的成员表 .innerJoin('chat.members', 'member') // 筛选出包含目标两个用户的记录 .where('member.id IN (:...userIds)', { userIds: [id1, id2] }) // 按聊天ID分组 .groupBy('chat.id') // 仅保留同时包含两个用户的分组(统计数等于2) .having('COUNT(member.id) = :count', { count: 2 }) // 获取唯一符合条件的聊天(因为每个双用户聊天唯一) .getOne();
方案二:查询并加载成员关系
如果需要同时加载聊天的members关联数据,可添加leftJoinAndSelect:
const chat = await this.chatRepository .createQueryBuilder('chat') .innerJoin('chat.members', 'member') .where('member.id IN (:...userIds)', { userIds: [id1, id2] }) .groupBy('chat.id') .having('COUNT(member.id) = :count', { count: 2 }) // 加载所有成员数据 .leftJoinAndSelect('chat.members', 'allMembers') .getOne();
性能优势说明
- 直接在数据库层面完成过滤,避免加载大量无关数据到内存
- 利用数据库索引(
members.id和中间关联表的索引)大幅提升查询速度 - 分组统计逻辑由数据库引擎优化,比内存遍历效率高几个数量级
内容的提问来源于stack exchange,提问作者user22128783
相关产品推荐
相关产品推荐

