Lưu ý rằng theo cách bạn đang cố gắng thực hiện, bạn có thể nhận được nhiều hàng cho mỗi mục (một lần cho mỗi danh sách có liên quan). Cách tốt hơn là có một loạt các danh sách cho mỗi mặt hàng.
Nếu bạn sử dụng các mô hình hùng hồn và bạn đã thiết lập các mối quan hệ một cách chính xác, bạn có thể thử các cách sau:
$cats = [1, 2, 3];
$query = Item::with('listings');
foreach ($cats as $cat) {
$query->whereHas('catitems', function($q) use($cat) {
$q->where('id', $cat);
});
}
$items = $query->get();
Giờ đây, mọi mặt hàng đều có listings
tài sản. Ví dụ:đối với mục đầu tiên, bạn có thể truy cập danh sách theo cách sau:
$item1 = $items[0];
$listings1 = $item1->listings;
Lưu ý rằng whereHas()
có thể sẽ tạo một EXISTS
tương quan truy vấn con cho mọi mục nhập trong $cats
mảng. Nếu điều đó diễn ra chậm, bạn có thể sử dụng truy vấn JOIN như:
$items = Item::with('listings')
->join('catitem_item', 'catitem_item.item_id', '=', 'items.id')
->whereIn('catitem_item.catitem_id', $cats)
->groupBy('items.id')
->having(DB::raw('count(*)'), '=', count($cats))
->select('items.*')
->get();
Nếu bạn không sử dụng tài hùng biện, bạn cũng có thể tự mình thực hiện "tải nhanh".
$items = DB::table('items')
->join('catitem_item', 'catitem_item.item_id', '=', 'items.id')
->whereIn('catitem_item.catitem_id', $cats)
->groupBy('items.id')
->having(DB::raw('count(*)'), '=', count($cats))
->select('items.*')
->get()
->keyBy('id');
foreach ($items as $item) {
$item->listings = [];
}
$itemIds = $items->pluck('id');
$listings = DB::table('listings')
->join('item_listing', 'item_listing.listing_id', '=', 'listings.id')
->whereIn('item_listing.item_id', $itemIds)
->groupBy('listings.id')
->select('listings.*', DB::raw('group_concat(item_listing.item_id) as item_ids'))
->get();
foreach ($listings as $listing) {
$itemIds = explode(',', $listing->item_ids);
foreach ($itemIds as $itemId) {
$items[$itemId]->listings[] = $listing;
}
$listing->forget('item_ids');
}