TypeORM多对多关联查询:按分类筛选产品并返回全部关联分类
问题根因
你之前的写法是在关联categories后直接添加筛选条件,会过滤掉关联结果集中所有分类ID不等于指定值的行,因此最终返回的产品关联分类仅剩下用于筛选的那一条。
方案1:双关联查询(写法最简洁)
对分类做两次关联,第一次仅用于筛选不返回字段,第二次加载产品关联的全部分类:
async findProductsByCategory(id: number): Promise<Product[]> { return this.productRepository .createQueryBuilder("product") // 仅做筛选用的分类关联,不加载字段 .leftJoin("product.categories", "filterCategory") // 加载产品关联的全部分类 .leftJoinAndSelect("product.categories", "category") .where("filterCategory.id = :id", { id }) .getMany(); }
方案2:子查询筛选(大数据量下性能更优)
先通过子查询定位到所有归属指定分类的产品ID,再基于ID查询产品完整信息和全部分类,避免多余的关联数据扫描:
async findProductsByCategory(id: number): Promise<Product[]> { // 子查询:查询所有归属指定分类的产品ID const filteredProductIdsQuery = this.productRepository .createQueryBuilder("subProduct") .leftJoin("subProduct.categories", "filterCategory") .where("filterCategory.id = :id", { id }) .select("subProduct.id") .getQuery(); // 主查询:加载符合条件产品的完整信息与全部分类 return this.productRepository .createQueryBuilder("product") .leftJoinAndSelect("product.categories", "category") .where(`product.id IN (${filteredProductIdsQuery})`) .setParameter("id", id) .getMany(); }
中小数据量场景优先选方案1即可,数据量较大时推荐使用方案2,两种方案都能实现按指定分类筛选的同时返回产品的全部关联分类。
内容的提问来源于stack exchange,提问作者Ian Wong
相关产品推荐
相关产品推荐

