Louis
Louis

Reputation: 103

Algolia rails sortBy dynamically

I'm building a search using Algolia rails but having difficulties when doing sort by dynamically. For example, user can choose from a dropdown to sort by price asc or price desc.

Here is my model where I defined the indices

class Product < ActiveRecord::Base
  include AlgoliaSearch

  algoliasearch per_environment: true, if: :publishable? do
    attribute :id, :name, :description, :seller_id, :condition, :location, :slug, :status, :city, :state, :stock_quantity,
      :shipping_method, :price
    attribute :created_at_i do
      created_at.to_i
    end
    attribute :updated_at_i do
      updated_at.to_i
    end
    attribute :price do
      price.to_f
    end
    attributesToIndex ['name', 'unordered(description)', 'seller_id',
      'condition', 'location', 'slug', 'created_at', 'updated_at', 'status',
      'geo(city)', 'geo(state)']
    geoloc :latitude, :longitude
    numericAttributesToIndex ["price", "stock_quantity"]
    attributesForFaceting ['price', 'condition', 'shipping_method']
  end

and the products controller

def index
queries = { hitsPerPage: 5, page: params[:page].to_i, facets: '*',
      facetFilters: [
        "condition: #{params[:condition]}",
        "shipping_method: #{params[:shipping_method]}"
      ],
      numericFilters: [
        "price:#{params[:min_price] || 0} to #{params[:max_price] || 999999999999999}"
      ],
      sortBy: ["asc(price)"]
    }

    if latLng.present?
      queries[:aroundLatLng] = latLng
      queries[:aroundRadius] = radius
    end


    @response = Product.search(params[:query],queries)

Algolia returns error "invalid parameter sortBy". I tried to search on algolia documentation but couldn't find any information. Thanks for helping.

Upvotes: 1

Views: 620

Answers (1)

Jerska
Jerska

Reputation: 12032

Here is a list of relevant documentation pages from Algolia's website which will help you understand how Algolia's ranking work:

  • [Getting started] Tweak Ranking and Relevance

    The reason our engine is so fast is because each index has its own settings and rankings. This means you are able to create different sets of searchable attributes and attribute ranking relevance by storing your data in multiple indices. This is accomplished using slave indices which are seamlessly synchronized with a master index. Each slave index can then be configured with its own set of business metrics to tune the relevance calculation.

    An index has a specific ranking formula that can't be changed. You can however easily overcome this limitation by using slave indices with a different ranking formula.

  • [Tutorials][Ranking Formula] Tie Breaking algorithm
    [FAQ] How does Algolia's tie breaking algorithm work?
    These two links will help you understand how the ranking with Algolia work and how you can tweak it. Basically, depending on your use-case, sorting by price before text relevance doesn't really make sense. So, depending on your use case, you might just want to change your customRanking to price, or you might want to add your price attribute at the top of your ranking formula.

  • [FAQ] What are slave indices and what are their benefits?
    This last link explain in more depth what a "slave index" is for Algolia.
  • [Rails documentation] Multiple sort criteria
    [Rails GitHub documentation] Master/Slave
    On these last links, you'll find code examples using Algolia's Rails client with multiple slaves. The first one actually showcases exactly your use case: sorting by price.

With all of this in mind, in the end, you're just looking to add these in your model (if you want to use the customRanking way):

add_slave 'Product_by_price_asc', per_environment: true do
  customRanking ['asc(price)']
end

add_slave 'Product_by_price_desc', per_environment: true do
  customRanking ['desc(price)']
end

Then in your controller, you can query them this way

query_params = { slave: "Product_by_price_#{params[:sort_order]}", hitsPerPage: 5, ... }
Product.search params[:query], query_params

You should probably also do this implementation in the front-end to be able to fully use Algolia's instant search capabilities, see [FAQ] Searching from the front-end or the back-end.

Upvotes: 1

Related Questions