Sequelize多对多关联:筛选Offer后返回其全部Tag的方案
解决Sequelize多对多关联查询时返回全部关联标签的问题
你当前的查询写法会让Sequelize执行内连接,仅返回匹配IN条件的Tag,同时筛选出关联这些Tag的Offer,但Offer的关联Tag列表也被一并过滤了。要实现「筛选包含指定Tag的Offer,同时返回这些Offer的所有关联Tag」,需要把筛选条件从include的Tag配置中移到主查询的where里,通过关联表判断Offer是否符合条件,而include Tag时不附加任何过滤条件。
修改后的查询代码(推荐使用Op.exists方式)
return await Offer.findAll({ include: [ Customer, { model: Tag, through: { attributes: [] } } ], where: { [Op.exists]: sequelize.literal(` SELECT 1 FROM offer_tags WHERE offer_tags.offer_id = offer.id AND offer_tags.tag_id IN (1, 2, 3, 4, 5) `) } });
另一种ORM化的子查询写法
如果不想用原生SQL片段,可以通过子查询获取符合条件的Offer ID列表,再以此筛选Offer:
return await Offer.findAll({ include: [ Customer, { model: Tag, through: { attributes: [] } } ], where: { id: { [Op.in]: await sequelize.queryInterface.select(OfferTags, { attributes: ['offer_id'], where: { tag_id: { [Op.in]: [1, 2, 3, 4, 5] } } }) } } });
原理说明
- 筛选逻辑移到主查询
where:通过判断offer_tags表中是否存在当前Offer关联的指定Tag ID,精准筛选出符合条件的Offer。 includeTag时不设where:此时Sequelize会执行正确的关联查询,返回该Offer的所有关联Tag,不会过滤掉非指定的Tag。
内容的提问来源于stack exchange,提问作者Clx3
相关产品推荐
相关产品推荐

