Objection/Knex中使用withGraphFetched查询排除无关联offer的品牌
解法1:使用whereExists关联查询(最推荐)
直接在品牌主查询中添加存在性校验,全程使用Objection原生API,无手写SQL,完全兼容所有模型特性:
const brandModel = this.objection.models.brand const query = brandModel.query() // 仅保留存在关联offer的品牌,自动处理关联条件无需手写SQL .whereExists(brandModel.relatedQuery('offer')) .withGraphFetched('offer') .page(page, page_size) const offers = await query
原理是whereExists会在生成的SQL中添加子查询,过滤掉没有对应offer的品牌记录,分页统计的总数也会自动适配过滤后的结果,不会出现分页偏移错误。
解法2:使用innerJoin关联去重
如果更习惯用关联查询的方式,可以用内连接+去重实现:
const brandModel = this.objection.models.brand const query = brandModel.query() .innerJoin('offers', 'brands.id', 'offers.brand_id') // 去重避免同一个品牌对应多个offer时返回重复记录 .distinct('brands.*') .withGraphFetched('offer') .page(page, page_size) const offers = await query
补充优化建议
你当前Brand模型中一对多关联的命名是单数offer,和返回结果中的复数offers字段语义不符,建议修改关联命名更符合开发习惯:
// Brand模型的relationMappings修改为 return { offers: { // 改为复数 relation: Model.HasManyRelation, modelClass: Offer, join: { from: 'brands.id', to: 'offers.brand_id' } } } // 查询时对应修改关联名即可 .withGraphFetched('offers')
内容的提问来源于stack exchange,提问作者JamesG。
相关产品推荐
相关产品推荐

