【问题标题】:Query on Eloquent based on relationship基于关系的 Eloquent 查询
【发布时间】:2020-05-13 03:13:29
【问题描述】:

我有 2 个模型,TransactionTrackingNumber

关系和字段是:

Transaction: hasMany TrackingNumber

Transaction fields: id | carrier
TrackingNumber fields: id | transaction_id

我正在尝试查询 TrackingNumbers,但我只想返回承运人为 ups 的位置。从这个意义上说:


a) 如果我使用预加载,它会返回所有的跟踪号码,而不考虑托运人,并且只返回基于 where 的交易关系:

$collection = TrackingNumber::with(['transaction' => function($q) {
    $q->where('carrier', 'ups')
}])->get();

所以这不是我想要的。我想要的是 $collection 只有给定运营商的 TrackingNumbers。


b) 如果我做这样的事情,结果就是我想要的,但是效率很低(因为它会进行 2 次查询并将数据存储在数组中;如果数组太大,它也会失败其中。)

$transactionIds = Transaction::where('carrier', 'ups')->pluck('id');
$trackingNumbers = TrackingNumber::whereIn('id', $transactionIds)->get();

// The result is what I want but it is inefficient.

c) 我也尝试过类似的方法,但它并不关心位置:/

\DB::table('tracking_numbers')
   ->join('transactions', 'tracking_numbers.transaction_id', '=', 'transactions.id')
   ->where('transactions.carrier', 'ups')
   ->get();

d) 我不想使用 whereHas(),因为它在处理大量数据时变得非常缓慢(我的表中有 +1m 行)


Laravel 的实现方式是什么?

【问题讨论】:

标签: laravel eloquent query-builder


【解决方案1】:

使用whereHas 应该可以得到你想要的结果:

TrackingNumber::whereHas('transaction', function ($query) {
    $query->where('carrier', 'ups');
})->get();

或者,尝试从 c 重构查询,例如:

\DB::table('tracking_numbers')
   ->join('transactions', function ($join) {
        $join->on('tracking_numbers.transaction_id', '=', 'transactions.id')
             ->where('transactions.carrier', 'ups');
   })
   ->get();

【讨论】:

  • whereHas 是实现这一目标的最慢方法 - 对于大数据,它非常慢(我的表有 +1m 行)
猜你喜欢
  • 2013-11-30
  • 2021-06-10
  • 2013-10-03
  • 2017-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-25
  • 2015-01-21
相关资源
最近更新 更多