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

时间:2016-09-09 00:05:25

标签: javascript orm bookshelf.js knex.js

如何在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调试器显示针对数据库执行的两个单独查询之外,这是有效的。我希望书架足够智能,可以构建连接在一个查询中的SQL。

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

1 个答案:

答案 0 :(得分:1)

我花了很长时间来解决这个问题,但多重查询行为是设计使然。 Bookshelf支持多次未加入的连接往返,但不是N + 1。它每个表查询一次。通过打破查询,如果由于节点的异步性质而导致单个表有多个连接,则可以并行运行一些查询。这是一种权衡,对于深层嵌套的关系没有意义,但可能适用于具有许多第一代关系的数据模型。我从来没有检查是否存在任何类型的事务或行锁定。

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

如果您正在进行非常复杂的查询,其中性能需要连接,我可能建议只使用knex或knex.raw而不是bookshelf。