排序的艺术

如果你还没听说,Meilisearch v0.22已经发布了,它带来了一个备受期待的新功能:搜索时排序。
搜索时排序是指根据查询时决定的参数对结果进行排序。默认情况下,Meilisearch 根据其相关性对结果进行排序,但你可以对其进行配置,让用户在搜索时决定他们想首先看到哪些结果。
让我向你展示这个功能有多强大。如果我想搜索MacBook并按价格升序排序结果,我将发送以下查询:
curl -X POST 'http://:7700/indexes/computers/search' --data '{ "q": "MacBook", "sort": [ "price:asc" ] }'
我也可以反向操作,按价格降序搜索。我只需在我的请求中将asc
替换为desc
。
旧方式
在Meilisearch v0.22之前,你只能使用自定义排名规则来对搜索结果进行排序。
多亏了自定义排名规则,我们可以按我们选择的数字属性对搜索结果进行排序。然而,排序不是在搜索时进行的,排序顺序是在我们的索引设置中决定的。
为了更改用户界面中搜索结果的排序顺序,我们必须复制索引并为每个索引设置不同的自定义排名规则。
几个月前,我就是为我们的MoMA演示这样做的。对于那些错过的人来说,MoMA演示是一个用现代艺术博物馆的艺术品数据集创建的Meilisearch演示,该数据集可在其GitHub仓库中找到。你可以在这篇博客文章中了解更多关于这个演示的信息。我想让用户能够按日期对艺术品进行排序,所以我不得不创建三个索引:
- artWorks
使用默认内置排名规则
- artWorksAsc
使用自定义排名规则进行升序排序
- artWorksDesc
使用自定义排名规则进行降序排序
// Get or create indexes const artWorksIndex = await client.getOrCreateIndex('artWorks', { primaryKey: 'ObjectID' }) const artWorksAscIndex = await client.getOrCreateIndex('artWorksAsc', { primaryKey: 'ObjectID' }) const artWorksDescIndex = await client.getOrCreateIndex('artWorksDesc', { primaryKey: 'ObjectID' }) const defaultRankingRules = [ 'typo', 'words', 'proximity', 'attribute', 'exactness' ] const rankingRulesAsc = [ 'typo', 'words', 'proximity', 'attribute', 'exactness', 'asc(DateToSortBy)' // ascending sort ] const rankingRulesDesc = [ 'typo', 'words', 'proximity', 'attribute', 'exactness', 'desc(DateToSortBy)' // descending sort ]
由于Meilisearch速度极快,这种复制(或三倍复制)给人的印象是搜索时排序。
当时,排序在我们的路线图中,位于“正在考虑”选项卡下,它是投票最多的功能之一(86票)。
我们有一个公开路线图,你可以在上面提交功能或集成想法,并为现有的投票。
使用新的v0.22排序功能
今天,这已经成为现实。我更新了演示以集成此功能。让我们看看有什么变化。
幕后
首先,我在设置中添加了以下行:
sortableAttributes: ['DateToSortBy']
此添加是必需的,因为我们需要告知Meilisearch我们希望用于排序的属性。
我们只需要一个索引(而不是三个)和默认排名规则。这大大减少了后端代码。你可以更改sort
规则的位置,根据你的需求调整搜索结果的相关性。默认情况下,sort
规则在排名规则中处于第5位,以提升与用户搜索相关的结果。
你可以在此处了解更多关于排名规则以及它们如何影响相关性的信息。
如果你好奇为什么sort
规则默认位于第5位,你可以查看这个GitHub issue,我们的产品经理在其中解释了这一选择。
通过这些修改,上面那一大段代码已经缩减为以下一行:
// Get or create the index const index = await client.getOrCreateIndex('artWorks', { primaryKey: 'ObjectID' })
很简单,对吧?但是,前端呢?
聚焦
在这个演示中,我使用了Vue InstantSearch,并结合了Instant Meilisearch。这连接了Meilisearch实例和开源的InstantSearch前端工具,使我们能够轻松定制搜索环境。
以前的代码是这样的:
<ais-sort-by :items="[ { value: 'artWorks', label: 'Featured' }, { value: 'artWorksAsc', label: 'Date asc.' }, { value: 'artWorksDesc', label: 'Date desc.' } ]" :class-names="{ 'ais-SortBy': 'MyCustomSortBy' }" />
我只需要把它变成这样:
<ais-sort-by :items="[ { value: 'artWorks', label: 'Featured' }, { value: 'artWorks:DateToSortBy:asc', label: 'Date asc.' }, { value: 'artWorks:DateToSortBy:desc', label: 'Date desc.' } ]" :class-names="{ 'ais-SortBy': 'MyCustomSortBy' }" />
如你所见,我们不再需要使用3个不同的索引(artWorks
、artWorksAsc
和artworksDesc
),我们只需将属性名称附加到artWorks
索引,然后加上所需的排序顺序,asc
或desc
。
'artWorks:DateToSortBy:asc' 'artWorks:DateToSortBy:desc'
就是这样。流畅而简单。你可以在这里测试它。
带有查询“Magritte”的网络界面,按升序和降序日期排序的GIF动画。
最终用户可能不会注意到区别,但从资源角度来看,效率更高。
v0.22的另一个巨大优势是新的索引器。它比以前快得多,所以如果你仍在使用旧版本的Meilisearch,我强烈建议你升级它。
演示源代码可在GitHub上获取。我邀请你玩转它,你可以添加其他属性进行排序,只要它们是字符串或数值。有关排序的更深入解释,请查看文档的专用部分。
图片来自Héctor J. Rivas在Unsplash上发布