04. tháng 1 2025
Do số lượng dữ liệu trong bảng lịch sử duyệt lớn, nên không dám thực hiện thao tác join trực tiếp trên bảng này. Trong logic bắn cá miễn phí của API hiển thị danh sách bài viết đã xem gần đây, trước tiên chúng ta lấy tập hợp các ID bài viết mà người dùng đã xem gần nhất, sau đó sử dụng câu lệnh whereIn
để lấy thông tin chi tiết của các bài viết đó.
1$saves = VisitHistory::where('user_id', $user->id)
2 ->orderBy('id', 'desc')
3 ->offset($offset)
4 ->limit($limit)
5 ->get();
6$items = Post::with('user:id,name,is_master,avatar_url')
7 ->whereIn('id', $saves->pluck('post_id')->toArray())
8 ->where('status', 1)
9 ->get();
Tuy nhiên, cách làm như vậy sẽ gây ra một lỗi: danh sách bài viết trả về không theo đúng thứ tự mà người dùng đã xem. Điều này xảy ra vì câu lệnh whereIn
không đảm bảo giữ nguyên thứ tự của danh sách đầu vào.
Để giải quyết vấn đề này, chúng ta có thể sử dụng câu lệnh SQL ORDER BY FIELD
. Ví dụ:
1SELECT * FROM posts WHERE id IN (2, 7, 6, 9, 1)
2ORDER BY FIELD(id, 2, 7, 6, 9, 1);
Trong Laravel, chúng ta có thể triển khai giải j88 online pháp này như sau:
1$saves = VisitHistory::where('user_id', $user->id)
2 ->orderBy('id', 'desc')
3 ->offset($offset)
4 ->limit($limit)
5 ->get();
6$ids = $saves->pluck('post_id')->toArray();
7$ids_ordered = implode(',', $ids);
8
9$items = Post::with('user:id,name,is_master,avatar_url')
10 ->whereIn('id', $ids)
11 ->where('status', 1)
12 ->orderByRaw(DB::raw("FIELD(id, $ids_ordered)"))
13 ->get();
pluck('post_id')
: Lấy danh sách các ID bài viết từ kết quả truy vấn $saves
.implode(',', $ids)
: Chuyển đổi mảng ID thành chuỗi phân tách bởi dấu phẩy.orderByRaw
: Sử dụng câu lệnh tùy chỉnh để sắp xếp dựa trên thứ tự cụ thể của danh sách ID.Nhờ cách tiếp cận này, danh sách bài viết trả về sẽ luôn tuân thủ đúng thứ tự mà người dùng đã xem gần đây nhất.