You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bookshelf.js如何通过关联记录的匹配条件查询记录?

解决Bookshelf.js中查询拥有特定品牌汽车的Person问题

嘿,我懂你遇到的困扰了——直接在Person的where条件里嵌套cars字段是行不通的,因为Bookshelf不会自动帮你关联两张表,数据库压根找不到cars.make这个字段在persons表里。咱们来换几种正确的写法:

方法一:使用内连接(Inner Join)

这种方式直接关联Person和Car表,过滤出拥有Rover汽车的人,同时用distinct避免同一个人因为多辆Rover而重复出现:

Person.query((qb) => {
  qb.innerJoin('cars', 'persons.id', 'cars.person_id')
    .where('cars.make', 'Rover')
    .distinct('persons.id');
}).fetchAll()
  .then(persons => {
    // 处理查询到的Person结果
  })
  .catch(err => {
    // 处理错误
  });

方法二:使用WhereExists子查询

如果不想用join,子查询的方式更优雅,它会检查当前Person是否存在符合条件的关联Car,在大数据量场景下性能表现也不错:

Person.query((qb) => {
  qb.whereExists(function() {
    this.select('*')
      .from('cars')
      .whereRaw('cars.person_id = persons.id')
      .where('cars.make', 'Rover');
  });
}).fetchAll()
  .then(persons => {
    // 处理查询到的Person结果
  })
  .catch(err => {
    // 处理错误
  });

额外:如果需要同时返回关联的Rover汽车

如果你不仅要Person的基础数据,还要他们名下的Rover汽车信息,可以加上withRelated,同时用groupBy确保Person记录不重复:

Person.query((qb) => {
  qb.join('cars', 'persons.id', 'cars.person_id')
    .where('cars.make', 'Rover')
    .groupBy('persons.id');
}).fetchAll({ withRelated: ['cars'] })
  .then(persons => {
    // 每个person的cars属性里只会包含Rover品牌的汽车
  })
  .catch(err => {
    // 处理错误
  });

原来的写法之所以失效,是因为Person.query({ where: { cars: { make: 'Rover' } } })是直接针对persons表的条件查询,Bookshelf不会自动关联cars表,数据库会认为你在查询persons表的某个cars字段,自然找不到匹配的内容啦。

内容的提问来源于stack exchange,提问作者LongHike

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:28:34