Sorting search results by custom attribute(s) in Algolia

Prerequisites to use sorting

To sort the results of a search, you need to first create a so-called “replica index.”

“By design, Algolia provides one ranking formula per index: when you want to provide different rankings for the same data, you need to use different indices for each ranking. These additional indices are called replicas.”

This can be done either through the Algolia dashboard or their API. For detailed instructions, see the Algolia documentation.

After creating your [replica index] open the project.yml file in your GitHub project folder. Then you can add the sortIndices key under the algolia configuration.

There you'll be able to map your custom attributes to Algolia indices so Frontastic can choose the appropriate one to achieve sorting at query time.

Sorting by a single attribute

Under sortIndices in your project.yml create a key that's the name of your custom attribute.

Under there, you'll have to map each attribute and mode of sorting to an Algolia replica index.
The syntax is the following: attributeName_modeOfSorting: nameOfAlgoliaIndex

For example, say we want to allow our customers to sort products by their price. First, we'd need to create 2 indices in Algolia: 1 for ascending and 1 for descending order. Our Algolia configuration in project.yml would look like this:

configuration:
    productSearch:
        engine: algolia
    algolia:
        appId: ourAppId
        appKey: ourAppKey
        indexName: name_of_primary_index
        sortAttributes:
            price_ascending: products_price_asc
            price_descending: products_price_desc

For this configuration to work correctly, the sortAttributes field of your ProductQuery object should exactly be like this:

[
	'price' => 'ascending' // Or 'descending'
]

Sorting by multiple attributes

Like single attribute sorting, you'll first need to create replica indices in Algolia.

Under sortIndices in your project.yml, create a key that combines the name of your custom attributes and the modes of sorting separated by underscore characters.

Similarly to single attribute sorting the syntax is the following: nameOfAttribute_modeOfSorting_nameOfOtherAttribute_otherSortingMode...: algoliaIndexName

For example, say we want to allow our customers to order products by price and rating in either ascending or descending order.

📘

To keep this example simple, we don’t allow users to sort by price or rating individually. If you want to do so, see our example on sorting by a single attribute.

In Algolia, we need to create 4 different indexes to cover all sorting combinations:

  1. Price ascending rating ascending
  2. Price descending rating ascending
  3. Price ascending rating descending
  4. Price descending rating descending

After adding these to our Algolia project, we'd update our project.yml file to look like this:

configuration:
    productSearch:
        engine: algolia
    algolia:
        appId: ourAppId
        appKey: ourAppKey
        indexName: name_of_primary_index
        sortAttributes:
            price_ascending_rating_ascending: products_price_asc_rating_asc
            price_descending_rating_ascending: products_price_desc_rating_desc
	    price_ascending_rating_descending: products_price_asc_rating_desc
	    price_descending_rating_descending: products_price_desc_rating_desc

For this configuration to work correctly, the sortAttributes field of your ProductQuery object should exactly be like this:

[
	'price' => 'ascending' // Or 'descending'
	'rating' => 'ascending' // Or 'descending'
]

📘

The order you provide the attributes inside the array doesn't matter.

Sorting in multi-language projects

Just like the indexName property ˙sortIndices` can also be nested in the language of your choice.
If you haven't done so already, we recommend reading the localization search with Algolia article.

Below is an example of a project.yml file in a multi-language project:

configuration:
    productSearch:
        engine: algolia
    algolia:
        appId: ourAppId
        appKey: ourAppKey
        languages:
          en_GB@EUR:
            indexName: products_en_gbp
            sortIndices:
              price_asc: price_asc_en_gbp
              price_desc: price_desc_en_gbp
              price_asc_rating_desc: price_asc_rating_desc_en_gbp
         de_DE@EUR:
           indexName: dev_frontastic_search_de
           sortIndices:
             price_asc: price_asc_de_eur
             price_desc: price_desc_de_eur
             price_asc_rating_desc: price_asc_rating_desc_de_eur