Sorting

    By default, Meilisearch focuses on ordering results according to their relevancy. You can alter this sorting behavior so users can decide at search time what type of results they want to see first.

    This can be useful in many situations, such as when a user wants to see the cheapest products available in a webshop.

    TIP

    Sorting at search time can be particularly effective when combined with placeholder searches.

    Configuring Meilisearch for sorting at search time

    To allow your users to sort results at search time you must:

    1. Decide which attributes you want to use for sorting
    2. Add those attributes to the sortableAttributes index setting
    3. Update Meilisearch's ranking rules (optional)
    NOTE

    Meilisearch sorts strings in lexicographic order based on their byte values. For example, á, which has a value of 225, will be sorted after z, which has a value of 122.

    Uppercase letters are sorted as if they were lowercase. They will still appear uppercase in search results.

    Select attributes for sorting

    Meilisearch allows you to sort results based on document fields. Only fields containing numbers, strings, arrays of numeric values, and arrays of string values can be used for sorting.

    WARNING

    If a field has values of different types across documents, Meilisearch will give precedence to numbers over strings. This means documents with numeric field values will be ranked higher than those with string values.

    This can lead to unexpected behavior when sorting, so we strongly recommend you only allow sorting at query time on fields containing the same type of value.

    Adding attributes to sortableAttributes

    After you have decided which fields you will allow your users to sort on, you must add their attributes to the sortableAttributes index setting.

    sortableAttributes accepts an array of strings, each corresponding to one attribute. Note that the attribute order in sortableAttributes has no impact on sorting.

    Example

    Suppose you have collection of books containing the following fields:

    [
      {
        "id": 1,
        "title": "Solaris",
        "author": "Stanislaw Lem",
        "genres": [
          "science fiction"
        ],
        "rating": {
          "critics": 95,
          "users": 87
        },
        "price": 5.00
      },
      {
        "id": 2,
        "title": "The Parable of the Sower",
        "author": "Octavia E. Butler",
        "genres": [
          "science fiction"
        ],
        "rating": {
          "critics": 90,
          "users": 92
        },
        "price": 10.00
      },
      {
        "id": 3,
        "title": "Gender Trouble",
        "author": "Judith Butler",
        "genres": [
          "feminism",
          "philosophy"
        ],
        "rating": {
          "critics": 86,
          "users": 73
        },
        "price": 10.00
      },
      {
        "id": 4,
        "title": "Wild Seed",
        "author": "Octavia E. Butler",
        "genres": [
          "fantasy"
        ],
        "rating": {
          "critics": 84,
          "users": 80
        },
        "price": 5.00
      },]
    

    If you are using this dataset in a webshop, you might want to allow your users to sort on author and price:

    curl \
      -X PUT 'http://localhost:7700/indexes/books/settings/sortable-attributes' \
      -H 'Content-Type: application/json' \
      --data-binary '[
        "author",
        "price"
      ]'

    Customize ranking rule order (optional)

    When users sort results at search time, Meilisearch's ranking rules are set up so the top matches emphasize relevant results over sorting order. You might need to alter this behavior depending on your application's needs.

    This is the default configuration of Meilisearch's ranking rules:

    [
      "words",
      "typo",
      "proximity",
      "attribute",
      "sort",
      "exactness"
    ]
    

    "sort" is in fifth place. This means it acts as a tie-breaker rule: Meilisearch will first place results closely matching search terms at the top of the returned documents list and only then will apply the "sort" parameters as requested by the user. In other words, by default Meilisearch provides a very relevant sorting.

    Placing "sort" ranking rule higher in the list will emphasize exhaustive sorting over relevant sorting: your results will more closely follow the sorting order your user chose, but will not be as relevant.

    Promoting search results and document pinning

    Sorting applies equally to all documents. Meilisearch does not offer native support for promoting, pinning, and boosting specific documents so they are displayed more prominently than other search results. Consult these Meilisearch blog articles for workarounds on implementing promoted search results with React InstantSearch and document boosting.

    Example

    If your users care more about finding cheaper books than they care about finding specific matches to their queries, you can place sort much higher in the ranking rules:

    curl \
      -X PUT 'http://localhost:7700/indexes/books/settings/ranking-rules' \
      -H 'Content-Type: application/json' \
      --data-binary '[
        "words",
        "sort",
        "typo",
        "proximity",
        "attribute",
        "exactness"
      ]'

    Sorting results at search time

    After configuring sortableAttributes, you can use the sort search parameter to control the sorting order of your search results.

    Using sort

    sort expects a list of attributes that have been added to the sortableAttributes list.

    Attributes must be given as attribute:sorting_order. In other words, each attribute must be followed by a colon (:) and a sorting order: either ascending (asc) or descending (desc).

    When using the POST route, sort expects an array of strings:

    "sort": [
      "price:asc",
      "author:desc"
    ]
    

    When using the GET route, sort expects a comma-separated string:

    sort="price:desc,author:asc"
    

    We strongly recommend using POST over GET routes whenever possible.

    The order of sort values matter: the higher an attribute is in the search parameter value, the more Meilisearch will prioritize it over attributes placed lower. In our example, if multiple documents have the same value for price, Meilisearch will decide the order between these similarly-priced documents based on their author.

    Example

    Suppose you are searching for books in a webshop and want to see the cheapest science fiction titles. This query searches for "science fiction" books sorted from cheapest to most expensive:

    curl \
      -X POST 'http://localhost:7700/indexes/books/search' \
      -H 'Content-Type: application/json' \
      --data-binary '{
        "q": "science fiction",
        "sort": ["price:asc"]
      }'

    With our example dataset, the results look like this:

    [
      {
        "id": 1,
        "title": "Solaris",
        "author": "Stanislaw Lem",
        "genres": [
          "science fiction"
        ],
        "rating": {
          "critics": 95,
          "users": 87
        },
        "price": 5.00
      },
      {
        "id": 2,
        "title": "The Parable of the Sower",
        "author": "Octavia E. Butler",
        "genres": [
          "science fiction"
        ],
        "rating": {
          "critics": 90,
          "users": 92
        },
        "price": 10.00
      }
    ]
    

    It is common to search books based on an author's name. sort can help grouping results from the same author. This query would only return books matching the query term "butler" and group results according to their authors:

    curl \
      -X POST 'http://localhost:7700/indexes/books/search' \
      -H 'Content-Type: application/json' \
      --data-binary '{
        "q": "butler",
        "sort": ["author:desc"]
      }'
    [
      {
        "id": 2,
        "title": "The Parable of the Sower",
        "author": "Octavia E. Butler",
        "genres": [
          "science fiction"
        ],
        "rating": {
          "critics": 90,
          "users": 92
        },
        "price": 10.00
      },
      {
        "id": 5,
        "title": "Wild Seed",
        "author": "Octavia E. Butler",
        "genres": [
          "fantasy"
        ],
        "rating": {
          "critics": 84,
          "users": 80
        },
        "price": 5.00
      },
      {
        "id": 4,
        "title": "Gender Trouble",
        "author": "Judith Butler",
        "genres": [
          "feminism",
          "philosophy"
        ],
        "rating": {
          "critics": 86,
          "users": 73
        },
        "price": 10.00
      }
    ]
    

    Sorting by nested fields

    Use dot notation to sort results based on a document's nested fields. The following query sorts returned documents by their user review scores:

    curl \
      -X POST 'http://localhost:7700/indexes/books/search' \
      -H 'Content-Type: application/json' \
      --data-binary '{
        "q": "science fiction",
        "sort": ["rating.users:asc"]
      }'

    Sorting and custom ranking rules

    There is a lot of overlap between sorting and configuring custom ranking rules, as both can greatly influence which results a user will see first.

    Sorting is most useful when you want your users to be able to alter the order of returned results at query time. For example, webshop users might want to order results by price depending on what they are searching and to change whether they see the most expensive or the cheapest products first.

    Custom ranking rules, instead, establish a default sorting rule that is enforced in every search. This approach can be useful when you want to promote certain results above all others, regardless of a user's preferences. For example, you might want a webshop to always feature discounted products first, no matter what a user is searching for.

    Sorting with _geoPoint

    If your documents contain _geo data, you can use _geoPoint to sort results based on their distance from a geographic position.

    _geoPoint is a sorting function that requires two floating point numbers indicating a location's latitude and longitude. You must also specify whether the sort should be ascending (asc) or descending (desc):

    {
      "sort": [
        "_geoPoint(0.0, 0.0):asc"
      ]
    }
    

    Queries using _geoPoint will always include a geoDistance field containing the distance in meters between the document location and the _geoPoint:

    [
      {
        "id": 1,
        "name": "Nàpiz' Milano",
        "_geo": {
          "lat": 45.4777599,
          "lng": 9.1967508
        },
        "_geoDistance": 1532
      }
    ]
    

    You can read more about location-based sorting in our geosearch guide.

    Example

    The following query will sort results based on how close they are to the Eiffel Tower:

    curl \
      -X POST 'http://localhost:7700/indexes/restaurants/search' \
      -H 'Content-type:application/json' \
      --data-binary '{ "sort": ["_geoPoint(48.8561446,2.2978204):asc"] }'

    Example application

    Take a look at our demos for examples of how to implement sorting: