如何在TypeORM中使用loadRelationCountAndMap过滤并统计关联项?
如何在TypeORM中使用loadRelationCountAndMap过滤并统计关联项?
嘿,看你已经把TypeORM的一对多关联配置得顺顺当当的了!我来给你讲讲怎么用loadRelationCountAndMap来过滤并统计关联的订单数量,完全适配你现有的Wechat和Order实体结构。
首先,loadRelationCountAndMap的核心作用就是给主实体临时映射一个统计字段,你可以自定义这个字段的名字,还能通过条件精准过滤要统计的关联项。比如你想统计每个微信用户的已完成订单(假设status=2是已完成)数量,或者待处理订单数量,都能用它轻松实现。
基础用法:统计指定状态的订单数量
比如我要给每个Wechat对象加一个orderCompletedCount字段,专门统计它的status为2的订单数量,代码可以这么写:
const wechatUsers = await WechatEntity.createQueryBuilder('wechat') .loadRelationCountAndMap( 'wechat.orderCompletedCount', // 要映射到Wechat的临时字段名 'wechat.orders', // Wechat实体上定义的关联关系名 'orders', // 关联表Order的别名 (qb) => qb.where('orders.status = :status', { status: 2 }) // 过滤条件:只统计status=2的订单 ) .getMany();
执行这个查询后,每个返回的Wechat对象里就会多一个orderCompletedCount属性,值就是符合条件的订单数量。
进阶:同时统计多个条件的订单数量
如果你想同时统计已完成和待处理(比如status=1)的订单数量,只需要多次调用loadRelationCountAndMap就行,注意每次的关联表别名要不一样,避免冲突:
const wechatUsers = await WechatEntity.createQueryBuilder('wechat') // 统计已完成订单 .loadRelationCountAndMap( 'wechat.orderCompletedCount', 'wechat.orders', 'completedOrders', // 这里用completedOrders当别名,和下面的pendingOrders区分开 (qb) => qb.where('completedOrders.status = :completed', { completed: 2 }) ) // 统计待处理订单 .loadRelationCountAndMap( 'wechat.orderPendingCount', 'wechat.orders', 'pendingOrders', (qb) => qb.where('pendingOrders.status = :pending', { pending: 1 }) ) .getMany();
这样返回的每个Wechat对象就会同时有orderCompletedCount和orderPendingCount两个统计字段,一目了然。
过滤主实体:只返回有符合条件关联项的记录
如果你想只返回至少有1个已完成订单的微信用户,可以在查询里加上having条件:
const wechatUsers = await WechatEntity.createQueryBuilder('wechat') .loadRelationCountAndMap( 'wechat.orderCompletedCount', 'wechat.orders', 'orders', (qb) => qb.where('orders.status = :status', { status: 2 }) ) .having('wechat.orderCompletedCount > :count', { count: 0 }) .getMany();
这样就会自动过滤掉没有已完成订单的用户,只留下符合要求的记录。
一些要注意的小细节
- 我们映射的这些统计字段(比如
orderCompletedCount)是临时的,不需要在你的Wechat实体类里提前定义,查询结果会自动带上 - 过滤条件里的别名要和
loadRelationCountAndMap第三个参数的别名保持一致,比如上面的orders、completedOrders - 复杂的过滤条件也支持,比如用
IN匹配多个状态:qb.where('orders.status IN (:...statuses)', { statuses: [1,3] })
备注:内容来源于stack exchange,提问作者Panda
相关产品推荐
相关产品推荐

