You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeORM多对多关联innerJoin后如何通过关联表ID筛选结果

解决TypeORM多对多关联同时匹配多个关联项的筛选问题

核心逻辑

要筛选同时包含所有指定服务ID的医生,不能直接用IN条件(IN只需匹配任意一个ID即可),需要通过「统计匹配的服务数量是否等于目标ID数组长度」的方式判定是否完全匹配,同时为了保留TypeORM实体映射能力,采用子查询+主查询分离的方式实现。

实现代码

const servicesArray = [1, 2];

// 子查询:筛选出同时包含所有指定服务的医生ID列表
const matchedDoctorIds = await this.doctorsRepository
  .createQueryBuilder('doctor')
  .innerJoin('doctor.services', 'services')
  .where('services.id IN (:...ids)', { ids: servicesArray })
  .groupBy('doctor.id')
  // 若多对多中间表无重复关联记录,可去掉DISTINCT
  .having('COUNT(DISTINCT services.id) = :targetCount', { targetCount: servicesArray.length })
  .select('doctor.id')
  .getRawMany();

// 提取医生ID数组,字段名根据你的命名策略可能为doctorId/doctor_id,自行调整即可
const doctorIds = matchedDoctorIds.map(item => item.doctor_id);

// 主查询:查询符合条件的医生及关联服务
const result = await this.doctorsRepository
  .createQueryBuilder('doctor')
  .innerJoinAndSelect('doctor.services', 'services')
  .where('doctor.id IN (:...doctorIds)', { doctorIds })
  // 如果需要返回的services仅包含筛选的指定服务,可添加下面这行,完全匹配你给出的预期结果
  .andWhere('services.id IN (:...ids)', { ids: servicesArray })
  .getMany();

原方案问题说明

  • 直接使用services.id IN (:...ids)条件:只要医生关联了任意一个目标服务就会被返回,无法满足「同时包含所有目标服务」的要求
  • 直接在主查询添加统计字段和分组:getMany()方法只会映射实体定义的属性,额外的统计字段不会被识别,无法得到规范的实体结构,仅适合配合getRawMany()使用

内容的提问来源于stack exchange,提问作者ShaSha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 22:24:00