Rails中Searchkick分页问题:如何排除前3条实现分页?
The issue with adding offset:3 directly to your paginated query is that it conflicts with how pagination calculates offsets internally. When you use page: params[:page], the pagination logic already computes the offset as (page_number - 1) * per_page. Adding an explicit offset:3 adds that value to the calculated offset, leading to incorrect page boundaries—and if new records are added between page loads, you’ll end up with duplicate entries.
A more reliable approach is to exclude the IDs of the 3 latest looks from your paginated query instead of using an offset. Here’s how to adjust your code:
def index query = params[:query].presence || "*" conditions = { available: true } conditions[:look_tags] = params[:look_tags] if params[:look_tags].present? # Fetch the 3 most recent looks @last_3_looks = Look.search( query, where: conditions, order: { created_at: :desc }, limit: 3 ) # Exclude these 3 looks from the paginated results excluded_ids = @last_3_looks.map(&:id) if excluded_ids.present? conditions[:id] = { not: excluded_ids } end # Paginate the remaining looks normally @looks = Look.search( query, where: conditions, order: { created_at: :desc }, page: params[:page], per_page: 8 ) end
Why This Works:
- No Offset Conflicts: By excluding the specific IDs of the top 3 looks, the pagination logic works as intended—each page starts right after the previous page’s last item, without manual offset adjustments.
- Consistency: Even if new looks are added while the user is browsing, the excluded IDs stay fixed to the original 3 you fetched. This prevents duplicates caused by shifting result sets.
- Cleaner Logic: The query explicitly filters out the records you don’t want in the paginated section, making the code easier to understand and maintain.
If you’re using an older version of Elasticsearch Rails where the not operator in the where clause isn’t supported, you can use a bool filter instead:
# Replace the conditions[:id] line with this conditions = conditions.merge( bool: { must_not: [ { terms: { id: excluded_ids } } ] } )
This will achieve the same exclusion effect using Elasticsearch’s native bool query syntax.
内容的提问来源于stack exchange,提问作者Benoît Bargès

