Sequelize子子模型过滤异常:查询返回全部Event而非匹配项求助
问题原因与解决方案
我来帮你拆解这个问题——你遇到的情况其实是Sequelize关联查询中过滤条件作用层级不匹配导致的。
问题根源
你的查询逻辑是在最内层的Game模型上加了where和required: true,这确实会过滤出符合玩家ID条件的Game,同时因为required: true,只有关联了这些Game的SubEvent会被保留。但关键在于:你对Event和SubEvent的关联没有设置强制过滤——默认情况下,Event.findAll里的include是左外连接(required: false),也就是说,哪怕某个Event没有任何符合条件的SubEvent,它依然会被查询出来,只是对应的SubEvent数组是空的。这就是为什么你会拿到全部Event实例。
修复方案
你需要在两层关联上都设置required: true,让过滤逻辑向上传递,确保只有关联了符合条件的SubEvent(进而关联符合条件的Game)的Event才会被返回。修改后的代码如下:
await models.Event.findAll({ "include": [ { "model": models.SubEvent, "required": true, // 关键:强制只保留有符合条件SubEvent的Event "include": [ { "model": models.Game, "where": { [models.Sequelize.Op.or]: { "player1Team1Id": args.playerId, "player2Team1Id": args.playerId, "player1Team2Id": args.playerId, "player2Team2Id": args.playerId } }, "required": true // 保留有符合条件Game的SubEvent } ] } ] });
额外说明
required: true等价于SQL中的INNER JOIN,会过滤掉没有关联子模型的父模型;而默认的required: false是LEFT OUTER JOIN,会保留所有父模型,不管有没有匹配的子模型。- 如果你希望允许
Event存在,但只返回符合条件的SubEvent和Game(而不是过滤掉整个Event),那可以去掉Event关联SubEvent时的required: true,但此时你需要在代码里手动过滤掉SubEvent为空的Event实例。
内容的提问来源于stack exchange,提问作者Kiwi
相关产品推荐
相关产品推荐

