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

如何用Objection Relation Mapping实现OR条件的关联查询?

Objection.js实现OR条件关联JOIN的解决方案

要实现JOIN Records ON Accounts.id = Records.account_id OR Accounts.id = Records.from_account_id这种带OR条件的关联,不能直接在join.to中写OR表达式——因为Objection的默认from/to关联仅支持简单的等值匹配,无法解析OR逻辑。以下是两种可行的解决方法:

方法一:自定义关联的ON子句(推荐)

在Account模型的关联配置中,放弃使用from和to,改用join回调手动构建包含OR条件的ON子句:

const { Model } = require('objection');
const Record = require('./Record');

class Account extends Model {
  static get tableName() {
    return 'Accounts';
  }

  static get relationMappings() {
    return {
      allRecords: {
        relation: Model.HasManyRelation,
        modelClass: Record,
        join: (joinBuilder) => {
          joinBuilder
            .on('Accounts.id', '=', 'Records.account_id')
            .orOn('Accounts.id', '=', 'Records.from_account_id');
        }
      }
    };
  }
}

使用时直接通过关联字段查询即可:

const accounts = await Account.query().withGraphFetched('allRecords');

这会自动生成你需要的带OR条件的JOIN语句,返回的每个Account对象的allRecords字段会包含所有匹配的Record数据。

方法二:查询时手动添加自定义JOIN

如果不想修改模型的关联配置,也可以在查询阶段直接用joinRaw添加自定义JOIN逻辑,再手动整理结果:

const accountsWithRecords = await Account.query()
  .leftJoinRaw('LEFT JOIN Records ON Accounts.id = Records.account_id OR Accounts.id = Records.from_account_id')
  .select('Accounts.*', 'Records.id as record_id', 'Records.amount') // 按需选择字段
  .groupBy('Accounts.id', 'Records.id')
  .then(results => {
    // 手动将同一Account的Records合并到数组中
    const accountMap = new Map();
    results.forEach(row => {
      const accountId = row.id;
      if (!accountMap.has(accountId)) {
        accountMap.set(accountId, { ...row, records: [] });
      }
      if (row.record_id) {
        accountMap.get(accountId).records.push({ id: row.record_id, amount: row.amount });
      }
    });
    return Array.from(accountMap.values());
  });

这种方式适合临时查询场景,但需要手动处理结果分组。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 18:23:10