TypeORM使用QueryBuilder过滤关联数组仅返回匹配项问题求助
问题原因
你直接对leftJoinAndSelect关联出的tags表添加了全局where过滤条件,数据库执行关联查询时,只会保留符合标签过滤规则的关联行,TypeORM做结果映射时,自然只会把这些匹配到的标签组装到tags数组中,其余不符合过滤条件的标签就会被丢弃。
解决方法
推荐使用子查询先筛选出符合标签过滤条件的故事ID,再用这些ID查询完整的故事实体和全部关联数据,既可以正确过滤故事范围,也能保留故事关联的所有标签:
const queryBuilder = this.storyRepository .createQueryBuilder('story') .leftJoinAndSelect('story.tags', 'tags') .leftJoinAndSelect('story.fandoms', 'fandoms') .leftJoinAndSelect('story.author', 'author') .leftJoinAndSelect('story.rating', 'rating') .leftJoinAndSelect('story.focus', 'focus') // 包含标签过滤逻辑 if (filterQuery.tags) { const tags = filterQuery.tags.split(';') // 子查询:获取所有包含指定标签的故事ID const matchedStoryIds = this.storyRepository .createQueryBuilder('subStory') .leftJoin('subStory.tags', 'subTags') .where('subTags.title IN (:...tags)', { tags }) .select('subStory.id') .getQuery() queryBuilder.andWhere(`story.id IN ${matchedStoryIds}`) } // 排除标签过滤逻辑 if (filterQuery.excludeTags) { const tags = filterQuery.excludeTags.split(';') // 子查询:获取所有包含要排除标签的故事ID const excludedStoryIds = this.storyRepository .createQueryBuilder('subStory') .leftJoin('subStory.tags', 'subTags') .where('subTags.title IN (:...tags)', { tags }) .select('subStory.id') .getQuery() queryBuilder.andWhere(`story.id NOT IN ${excludedStoryIds}`) } // 后续查询逻辑保持不变 const storyCount = await queryBuilder.getCount() const stories = await queryBuilder.getMany() return { stories: await Promise.all( stories.map(async (story) => { delete story.chapters return (await this.buildResponse(story, currentUserId)).story }) ), storyCount, }
这种写法将故事过滤和全量关联查询拆分,子查询仅负责筛选符合条件的故事范围,主查询基于筛选后的ID拉取完整关联数据,不会出现标签被截断的问题。
内容的提问来源于stack exchange,提问作者dupoy.
相关产品推荐
相关产品推荐

