默认情况下,Meilisearch 会根据相关性对结果进行排序。您可以修改这种排序行为,让用户能在搜索时自行决定优先显示哪种类型的结果。

这在许多场景下非常有用,例如当用户希望查看网店中最便宜的商品时。

结合使用占位符搜索时,搜索时排序会特别有效。

配置 Meilisearch 实现搜索时排序

要允许用户在搜索时对结果排序,您需要:

  1. 确定要用于排序的属性
  2. 将这些属性添加到 sortableAttributes 索引设置中
  3. 更新 Meilisearch 的排序规则(可选)

Meilisearch 会根据字节值对字符串进行字典序排序。例如,á 的字节值为 225,会排在 z(字节值 122)之后。

大写字母会按照小写形式排序,但在搜索结果中仍会显示为大写。

sortableAttributes 添加属性

Meilisearch 允许您根据文档字段对结果排序。只有包含数字、字符串、数值数组或字符串数组的字段才能用于排序。

确定允许用户用于排序的字段后,必须将其属性添加到 sortableAttributes 索引设置中。

如果某个字段在不同文档中的值类型不同,Meilisearch 会优先处理数值而非字符串。这意味着包含数值字段的文档会排在包含字符串值的文档之前。

这可能导致排序时出现意外行为。为了获得最佳用户体验,请仅对包含相同类型值的字段进行排序。

示例

假设您有一个包含以下字段的书籍集合:

[
  {
    "id": 1,
    "title": "Solaris",
    "author": "Stanislaw Lem",
    "genres": [
      "science fiction"
    ],
    "rating": {
      "critics": 95,
      "users": 87
    },
    "price": 5.00
  },

]

如果您在网店中使用这个数据集,可能希望允许用户按 authorprice 字段排序:

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

自定义排序规则顺序(可选)

当用户在搜索时进行排序时,Meilisearch 的排序规则默认配置会优先显示相关结果而非排序顺序。根据您的应用需求,可能需要调整这一行为。

以下是 Meilisearch 排序规则的默认配置:

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

"sort" 位于第五位。这意味着它作为决胜规则:Meilisearch 会先将与搜索词高度匹配的结果放在返回文档列表的顶部,然后再应用用户请求的 "sort" 参数。换句话说,默认情况下 Meilisearch 提供的是高度相关的排序。

"sort" 排序规则在列表中提高位置会强调完全排序而非相关排序:您的结果将更严格遵循用户选择的排序顺序,但相关性会降低。

排序对所有文档同等适用。Meilisearch 不原生支持提升、置顶或加权特定文档使其比其他搜索结果更突出。如需实现这些功能,请参考 Meilisearch 博客文章:使用 React InstantSearch 实现推广搜索结果文档加权 的变通方案。

示例

如果你的用户更关注找到更便宜的书籍,而不是精确匹配他们的查询,你可以将 sort 放在排序规则中更靠前的位置:

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

在搜索时排序结果

配置好 sortableAttributes 后,你可以使用 sort 搜索参数来控制搜索结果的排序顺序。

sort 需要一个已添加到 sortableAttributes 列表中的属性列表。

属性必须以 attribute:sorting_order 的形式给出。换句话说,每个属性后面必须跟一个冒号 (:) 和排序顺序:升序 (asc) 或降序 (desc)。

使用 POST 路由时,sort 需要一个字符串数组:

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

使用 GET 路由时,sort 需要一个逗号分隔的字符串:

sort="price:desc,author:asc"

sort 值的顺序很重要:属性在搜索参数值中的位置越高,Meilisearch 就会越优先考虑它,而不是排在后面的属性。在我们的示例中,如果多个文档的 price 值相同,Meilisearch 将根据它们的 author 来决定这些价格相近的文档之间的顺序。

示例

假设您在一个网店中搜索书籍,想要查看最便宜的科幻小说。这个查询会搜索 "science fiction"(科幻小说)类别的书籍,并按价格从低到高排序:

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

使用我们的示例数据集,结果如下:

[
  {
    "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
  }
]

根据作者姓名搜索书籍是很常见的需求。sort 参数可以帮助按作者分组结果。以下查询只会返回匹配搜索词 "butler" 的书籍,并按作者分组:

curl \
  -X POST 'MEILISEARCH_URL/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
  }
]

按嵌套字段排序

使用点标记法可以根据文档的嵌套字段对结果进行排序。以下查询按用户评分对返回的文档进行排序:

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

排序与自定义排名规则

排序和配置自定义排名规则之间存在很多重叠之处,因为两者都能显著影响用户最先看到哪些结果。

当您希望用户能够在查询时改变返回结果的顺序时,排序最为有用。例如,电商网站的用户可能希望根据价格对搜索结果进行排序,并能切换是优先显示最贵还是最便宜的商品。

而自定义排名规则则是为每次搜索建立默认的排序规则。当您希望某些结果无论如何都优先显示时,这种方法就很有用。例如,您可能希望电商网站始终将打折商品显示在最前面,无论用户搜索什么内容。

示例应用

查看我们的演示项目,了解如何实现排序功能: