Bookshelf.js / Knex.js嵌套在单个查询中

Bookshelf.js / Knex.js nested where in single query

本文关键字:js 单个 查询 嵌套 Knex Bookshelf      更新时间:2023-09-26

如何在bookshelf.js中合并相关模型的查询?

目前,ORM向我想要合并的数据库发出两个单独的查询。来自sequelize,可能是这样的:

Model.find({
  where: {
    someField: 'someValue'
  },
  include: [{
    model: OtherModel,
    as: 'otherModel',
    where: {
      someOtherField: 'someOtherValue' <--- part of the same query
    }
  }]
})

我在bookshelf.js中的当前设置(设置了ModelOtherModel之间的关系):

Model
  .where({ someField: 'someValue' })
  .fetch({ withRelated: [{
    otherModel: q => q.where({ 
      someOtherField: 'someOtherValue' 
    })
  }] });

这个工作,除了knex.js调试器显示对数据库执行两个单独的查询。我希望bookshelf足够聪明,可以构建SQL连接单个查询。

这是可以通过配置或其他方式避免的吗?

我花了很长时间才明白,但多重查询行为是设计好的。Bookshelf倾向于多次非连接往返,而不是连接,但不是N+1。它对每个表查询一次。通过分解查询,如果由于节点的异步特性,有多个连接到单个表,则可以并行运行一些查询。这种权衡对于深度嵌套关系来说没有意义,但对于具有许多第一代关系的数据模型来说可能有意义。我从来没有检查过是否有任何类型的事务或行锁定。

您可以使用Knex (http://knexjs.org/#Builder-join)强制连接,并将其混合到您的书架代码中,但是除了对时间最敏感和优化的应用程序之外,您可能不会注意到开销,除非您对DB的延迟很差。

如果你正在做非常复杂的查询,其中连接需要性能,我可能建议只使用knex或knex。原始的而不是书架。