如何让TypeORM在嵌套对象无值时返回空数组?
解决TypeORM嵌套对象无值时返回空数组的问题
你的问题出在当前查询的内连接逻辑上:where条件中嵌套的stores.userStores: { userId: userId }会要求必须存在匹配的store数据才会返回对应的area,所以当用户没有关联的store时,整个查询结果为空数组。
要实现「返回用户关联的area,无匹配store时stores字段为空数组」的需求,有两种可行方案:
方案一:使用QueryBuilder做左连接查询(推荐,性能更优)
通过QueryBuilder的左连接语法,确保即使没有匹配的store,area依然会被返回,同时只筛选出当前用户有权限的store:
const userAreas = await this.areaRepository .createQueryBuilder('area') // 关联用户的area权限,确保只返回用户有权限的area .leftJoin('area.userAreas', 'userArea', 'userArea.userId = :userId', { userId }) // 左连接store,并只保留当前用户有权限的store .leftJoinAndSelect( 'area.stores', 'store', 'EXISTS (SELECT 1 FROM user_store WHERE user_store.storeId = store.storeId AND user_store.userId = :userId)', { userId } ) .where('userArea.userId IS NOT NULL') .getMany(); // 处理部分area未返回stores字段的情况,确保为空数组 const processedAreas = userAreas.map(area => ({ ...area, stores: area.stores || [] }));
方案二:先查询再过滤(代码更简洁)
先查询所有用户有权限的area及关联的所有store,再在代码层面过滤出当前用户有权限的store,无匹配则设为空数组:
// 查询用户有权限的area,包含所有关联的store和对应的userStores let userAreas = await this.areaRepository.find({ where: { userAreas: { userId: userId } }, relations: ['stores', 'stores.userStores'] }); // 过滤每个area的stores,只保留当前用户有权限的条目 userAreas = userAreas.map(area => ({ ...area, stores: area.stores?.filter(store => store.userStores.some(us => us.userId === userId) ) || [] }));
两种方案对比:
- 方案一在数据库层面完成过滤,减少数据传输量,适合数据量大的场景
- 方案二代码更直观,适合数据量较小的场景
内容的提问来源于stack exchange,提问作者Hikaru Shindo
相关产品推荐
相关产品推荐

