根据 withGraphFetched 结果排除 Objection/Knex 查询的结果

Jam*_*esG 6 javascript database node.js knex.js objection.js

我的反对有两个模型 - “品牌”和“报价”。

品牌:

const { Model } = require('objection')

class Brand extends Model {
  static get tableName() {
    return 'brands'
  }

  ...

  static get relationMappings() {
    const Offer = require('./offer-model')

    return {
      offer: {
        relation: Model.HasManyRelation,
        modelClass: Offer,
        join: { from: 'brands.id', to: 'offers.brand_id' }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

提供:

const { Model } = require('objection')

class Offer extends Model {
  static get tableName() {
    return 'offers'
  }
}
Run Code Online (Sandbox Code Playgroud)

一个品牌有很多优惠,但我想使用 withGraphFetched 获取至少有 1 个优惠的品牌,排除没有优惠的品牌。这是我到目前为止所拥有的:

const brandModel = this.objection.models.brand
const query = brandModel.query().withGraphFetched('offer')
query.page(page, page_size)
const offers = await query
Run Code Online (Sandbox Code Playgroud)

这会返回“已加入”的数据,但也会返回没有优惠的品牌。例如:

[{
  id:1,
  name: 'brand 1',
  offers: [{offerId: 1, offerName: 'offer 1'}]
},{
  id:2,
  name: 'brand 2',
  offers: []
}]
Run Code Online (Sandbox Code Playgroud)

在上面的数据中,我不希望ID为2的品牌出现在结果集中。

我正在使用 Objection/Knex 对结果进行分页,因此在执行查询后我不能仅排除具有空对象数组的品牌。

我可以使用原始查询来实现此目的,但这意味着我无法使用 Objection 动态属性和 Objection 的其他一些关键部分。

谢谢!

nik*_*ong 2

您可以将 whereExists 添加到查询中;就像是

const query = brandModel.query()
    .withGraphFetched('offer')
    .whereExists(
        (qb) => qb.select('id').from('offers')
             .where('offers.brand_id', knex.ref('brands.id'))
    );
Run Code Online (Sandbox Code Playgroud)

即使 whereExists 位直接是 Knex,查询仍然会遍历您的模型,因此您在那里定义的内容应该仍然适用(也许除非您正在做一些非常疯狂的事情,直接影响 whereExists 中使用的列)