【发布时间】:2020-05-13 03:13:29
【问题描述】:
我有 2 个模型,Transaction、TrackingNumber。
关系和字段是:
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 的实现方式是什么?
【问题讨论】:
-
对于 c),你应该使用它作为
->join('transactions', function($join){ $join->on('tracking_numbers.transaction_id', '=', 'transactions.id')->where('transactions.carrier', 'ups'); }) -
另外,查看连接并将其用作雄辩的关系github.com/laravel/framework/issues/15169 和github.com/laravel/ideas/issues/329
标签: laravel eloquent query-builder