Question

I have TS 3.0.6, will_paginate 3.0.5 and sphinx 2.0.4

I paginate results in my search by using page option:

@products = Product.search(query_string, {
  order: ordering,
  ranker: :bm25,
  sql: { include: :images },
  with: {
    price_type_for_search => min_price_conditions..max_price_conditions,
    kind_cd: @params[:kind_cd],
    brand_id: [*@params[:brand_ids]],
    category_ids: categories_for_search,
    property_value_names: [*params[:property_value_names]].map{ |s| Zlib.crc32(s) },
  },
  page: @params[:page],
  per_page: @params[:per]
})

I get error like

query 0 error: offset out of bounds (offset=12, max_matches=12); query 1 error: offset out of bounds (offset=12, max_matches=12); query 2 error: offset out of bounds (offset=12, max_matches=12); query 3 error: offset out of bounds (offset=12, max_matches=12)

where 12 is the @params[:per] value.

Else I use will_paginate @products in my view, but I think that doesn't matter. Why I get an error? How can I avoid it?

I send these parameters to the search:

order: :created_at
ranker: :bm25,
sql: { include: :images },
with: {
  # no matter
},
page: 2,
per_page: 12

If I send per_page == 18 & page == 2, then I get query 0 error: offset out of bounds (offset=18, max_matches=18) et.c. If I send per_page == 12 & page == 3, I get (offset=36, max_matches=36) in my error.

Was it helpful?

Solution

Okay, I think I've figured it out. The issue here is that the facets method was called upon @products in the above example. Facet calls don't like the :page and :per_page options, as facet calls only have one page. Hence, viewing page two or more of the search results would throw an error.

A workaround (which I tested locally) is to put most of those search options in a shared method:

def common_search_options
  {
    order: ordering,
    ranker: :bm25,
    with: {
      price_type_for_search => min_price_conditions..max_price_conditions,
      kind_cd: @params[:kind_cd],
      brand_id: [*@params[:brand_ids]],
      category_ids: categories_for_search,
      property_value_ids: [*params[:property_value_ids]],
    }
  }
end

And then create separate objects for the search results and the facet results:

@products = Product.search(query_string, common_search_options.merge({
  sql: { include: :images },
  page: @params[:page],
  per_page: @params[:per]
}))

@product_facets = Product.facets(query_string, common_search_options)

And of course, you'll want to change any references of @products.facets to @product_facets. This will ensure that facet searches don't have the pagination options, and everything should now work smoothly.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top