Algolia Search
First. 什么是 algolia search?
根据algolia官方网站自我阐述:Algolia是一个托管搜索引擎,提供全文,数字和多面搜索,能够从第一次击键中提供实时结果。
Algolia强大的API可让您快速无缝地在网站和移动应用程序中实施搜索。我们的搜索API每月为成千上万的公司提供数十亿条查询,可在全球100ms之内提供相关结果。
简单直白的说就是一个提供云搜素服务的第三方平台。我们通过调用algolia的feed接口把一些我们想要呈现给用户的内容上传到algolia平台,可以是产品,文章,图片等等信息。
然后我们可以在自己的网站上通过构建前端或者后端搜素方式,把用户的关键词提交给algolia,同时algolia在很短的时间内容作出回应,返回给我们与搜索有关的内容。
Second. 建筑用户搜索界面
Algolia在官方文档中推荐我们使用InstantSearch (即时搜索),这种搜索方式提供的效果确认给人一种很即时的感觉,没得用户键盘键入一个字母,algolia都会返回结果集。
InstantSearch属于前端搜索范畴,构建前端搜索algolia支持的语言还是比较丰富的例如 js,React,Vue,ios...
使用js构建前端搜索根据文档真的是十分的方便,只需把文档中的案例代码复制粘贴稍做改动就可以达到自己想要的结果,不过仅仅是针对与比较简单的单个Index搜索。
对于同时搜索多个index的需求就比较复制麻烦了,index指的是我们在algolia后台设置的搜索内容分类,每一个index可以包含一种搜索内容,比如 article_index,product_index,
faq_index,当我们向algolia上传内容时就需要指明feed到哪个index.
构建前端搜索时algolia把每个小功能都封装成一个小部件,每个小部件中的参数说明也都十分明确,所以调用起来比较方便。
根据文档 :
const search = instantsearch({ indexName: 'instant_search', searchClient: algoliasearch( 'YourApplicationID', 'YourSearchOnlyAPIKey' ), }); // Add widgets // ... search.start();
这样一个定义就开启了使用algolia instantsearch,当然在这之前必须以及引入了algolia的基础js库,同时html中也要包含algolia所需要的内容渲染html,algolia会自动把返回的结果集
组装成固定的html填充入固定的html中,当然我们可以自己设置需要组装的结果集html结构
instantsearch.widgets .index({ indexName: 'instant_search' }) .addWidgets([ // Add widgets // ... ]);
向instantsearch中添加需要搜素的index
instantsearch.widgets.searchBox({ container: '#searchbox', });
指定页面中搜索容器的ID,添加搜索容器时有很多参数可供配置如下
instantsearch.widgets.searchBox({ container: string|HTMLElement, // Optional parameters placeholder: string, autofocus: boolean, searchAsYouType: boolean, showReset: boolean, showSubmit: boolean, showLoadingIndicator: boolean, queryHook: function, templates: object, cssClasses: object, });
每一项配置具体代表什么,可以去文档中详细研究:https://www.algolia.com/doc/api-reference/widgets/search-box/js/
从官方文档可得知添加完搜索容器后,algolia会自动填充一段html进入指定的id容器中,可通过配置更改部分填充的html
如果想自定义这段html也是可以的,不过不过比较麻烦,也可以在html插入完成后通过js加入自己想要的html,
关于触发搜索端的小部件还有好几个例如:configure,configureRelatedItems,panel,autocomplete,voiceSearch
但并一定都需要用到,根据自己的需要去选择一种简单快捷都方式。
Third. 下面介绍一下返回结果集的小部件
最重要的一个小部件hits,有关它的设定都是用来存放并现实结果集的
instantsearch.widgets.hits({ container: string|HTMLElement, // Optional parameters escapeHTML: boolean, templates: object, cssClasses: object, transformItems: function, });
每一项配置都会对结果集的输出显示造成影响
container : 存放结果集的html容器
escapeHTML : 是否从匹配字符串值中转义HTML实体
templates : 结果集列表显示的html
cssClasses : 要覆盖的基础默认的css类
transformItems : 接收项目,并在显示它们之前调用它。应该返回一个形状与原始数组相同的新数组。在映射要转换的项目以及删除或重新排序项目时很有用
代码案例:
instantsearch.widgets.hits({ container: '#hits', escapeHTML: false, cssClasses: { root: 'MyCustomHits', list: ['MyCustomHitsList', 'MyCustomHitsList--subclass'], }, transformItems(items) { return items.map(item => ({ ...item, name: item.name.toUpperCase(), })); }, templates: { empty: 'No results for <q>{{ query }}</q>', item: ` <h2> {{#helpers.highlight}}{ "attribute": "name" }{{/helpers.highlight}} </h2> <p>{{ description }}</p> `, }, });
关于结果集还有高亮显示小部件很实用,可以把搜索出来的关键字突出显示
Instantsearch.highlight({ attribute:string, hit:object, //可选参数 highlightTagName:string, }); instantsearch.widgets.hits({ container: '#hits', templates: { item: ` <h2>{{#helpers.highlight}}{ "attribute": "name" }{{/helpers.highlight}}</h2> <p>{{ description }}</p> `, }, }); instantsearch.highlight({ // ... attribute: 'actor.name', });
被突出显示内容会被套上一个mark标签,然后就可以去通过css自定义想要高亮显示的样式拉。
关于 snippet 小部件也很实用,它的设置是用来控制返回内容的,可以指定返回带有关键字的内容片段,
就像是只显示带有关键字的部分精简内容。
instantsearch.snippet({ attribute: string, hit: object, // Optional parameters highlightedTagName: string, }); search.addWidgets([ instantsearch.widgets.configure({ attributesToSnippet: ['description'], }) ]);
此外还有很多丰富功能的小部件,可以去 https://www.algolia.com/doc/api-reference/widgets/instantsearch/js/ 官方文档仔细研究
掌握以上说明案例,基本已经可以使用algolia去实现搜索功能拉。
但在实际开发中我遇到了很棘手的问题,根本就找到可以实现我想要的效果的小部件
我想要实现的效果,一次关键词搜索输入,去搜素四个index的内容,即返回四个不同的结果集,然后根据这四个不同结果集的内容的数量,
以及是否有结果去渲染显示不同css样式的模版。比如说有8个产品,或者有6个产品,或者没有产品结果集都会显示不同的样式。
最终通过不断的查看官方文档,我发现了一个 helper 助手,这真是一个 极好的 助手,它可以帮我去触发搜索,拿到结果集,拿到结果集之后
我就不在用algolia自带的模版渲染了,将其隐藏,通过这些结果集我去自己拼接html,去添加不同样式类名,从而达到效果。
关于helper助手的文档内容 : https://community.algolia.com/algoliasearch-helper-js/reference.html#results
里面涉及的使用案例,方法功能真的是太丰富了,仍然有待发现研究......