Sequelize如何基于Include关联模型条件实现count计数查询
Sequelize count 方法添加关联模型筛选实现
count方法本身和findAll共享绝大多数查询参数,直接传入include配置即可实现关联筛选,唯一需要注意的是一对多关联场景下要加去重配置,避免计数重复。
第一步:改造count工具函数
给原有函数增加入参支持传入关联配置,同时加上去重参数:
const countAllOrdersWhere = async (conditions, includeList = []) => Order.count({ where: conditions, include: includeList, // 以下两个配置是一对多关联计数的核心:避免同一订单因关联多条符合条件的orderItem被重复统计 distinct: true, col: 'Order.id' }) .then((count) => ({ count, error: null })) .catch((error) => ({ count: null, error }));
第二步:调用时传入关联筛选配置
你之前在findAll里用的include配置可以直接复用,不需要改逻辑:
// 构造OrderItem关联筛选规则 const orderItemFilter = { model: OrderItem, where: Sequelize.literal( itemIds && itemIds.length > 0 ? `"orderItems"."itemId" IN (${itemIds})` : 'true' ), attributes: [] // 不需要返回orderItem字段,减少查询字段提升性能 }; const { count, error: countError } = await countAllOrdersWhere( { [Op.or]: [ { userId: userIds, status }, { status, venueId }, ], }, [orderItemFilter] );
可选优化:避免手写SQL降低注入风险
如果不需要硬写原生语句,更推荐用Sequelize内置的操作符写筛选条件,框架会自动做参数转义:
const orderItemFilter = { model: OrderItem, where: itemIds?.length ? { itemId: { [Op.in]: itemIds } } : {}, attributes: [] };
注意事项
- 不要漏加
distinct: true配置:一个订单如果关联多条符合筛选条件的orderItem,join查询后会生成多条同订单id的记录,不去重的话统计出来的是匹配的orderItem条数,不是订单总数 - 嵌套关联同样支持:如果后续需要通过OrderItem再关联Item做更深层的筛选,直接在OrderItem的配置里加
include数组传入Item的规则即可,count方法对嵌套关联的支持和findAll完全一致 - 如果关联关系里设置了
required: false(左连接),记得在count的include配置里根据需求调整required值,要筛选匹配关联的场景建议设为required: true(内连接),性能更好
内容的提问来源于stack exchange,提问作者Alk
相关产品推荐
相关产品推荐

