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

Posted

技术标签:

【中文标题】Bookshelf.js / Knex.js 嵌套在单个查询中的位置【英文标题】:Bookshelf.js / Knex.js nested where in single query 【发布时间】:2016-09-09 00:05:25 【问题描述】:

如何合并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。

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

【问题讨论】:

【参考方案1】:

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

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

如果您正在执行需要连接以提高性能的非常复杂的查询,我可能会建议仅使用 knex 或 knex.raw 而不是 bookshelf。

【讨论】:

有趣。您是否有任何指向描述此行为的文档的链接?我觉得这很奇怪,然后继续使用 Sequelize。

以上是关于Bookshelf.js / Knex.js 嵌套在单个查询中的位置的主要内容,如果未能解决你的问题,请参考以下文章

Bookshelf.js 查询相关表行

通过 Bookshelf.js 流式传输数据

bookshelf.js 时间戳不起作用

为啥我们需要 bookshelf.js 的 fetch() 方法中的新对象?

与 bookshelf.js 的多个多对多关系

如何监听 Bookshelf.js 模型中的属性何时更新?