快给你的网站添加algolia全文索引吧

2023-06-0825 min 教程
cover image
AI摘要
这篇文章讲了为网站添加Algolia全文索引的必要性。全文检索可以提高搜索效果,支持交互式文本查询,处理自然语言和模糊匹配。Algolia是一个托管搜索引擎,提供高效、灵活和有洞察力的搜索,支持自然语言处理、个性化和动态重排。免费计划对小型项目足够,Algolia提供丰富的示例、API和前端组件。选择Algolia的原因是它无需单独部署,适用于小型博客项目。文章介绍了如何注册、获取appID和apiKey,并演示了后端处理逻辑,包括创建索引实例、初始化设置项以及对索引进行操作。

说在前面

为什么需要全文搜索

如果只是以标题、标签等对文章进行检索,搜索的效果一般较差,用户比较难找到自己所需要的,而全文检索会把文章内容进行分词并构建索引,可以支持大量基于交互式文本的查询,提供高度相关的搜索结果,处理自然语言和模糊匹配等问题。当然它也需要额外的存储空间和维护成本,对于结构化数据的搜索效率不如关系型数据库。全文检索的常见搜索引擎有Lucene,Solr,ElasticSearch等。

Algolia是什么

Algolia是一个提供软件和工具的托管搜索引擎,可以帮助你在你的网站和应用中实现高效、灵活和有洞察力的搜索。Algolia由两部分组成:搜索实现和搜索分析。Algolia还提供了自然语言处理、个性化、动态重排等功能。Algolia每个月为数千家公司提供数十亿次查询,无论在世界哪个地方,都能在100毫秒内提供相关结果。

也就是说我们只需要向algolia提供我们的数据,algolia会自动帮我们构建索引并提供查询的api,这样本地服务器的压力相对减轻,搜索性能也得到了保证,而且它提供的免费计划对于我的小型博客项目是完全够用的,algolia提供了丰富的示例、Api、前端组件库来方便用户将Algolia整合到他们的项目中去,现在我们能见到的很多静态博客、文档类项目都支持了Algolia。

为什么选择Algolia

如果要给我的go项目引入全文搜索的功能,一种途径我们可以使用上述提到的ElasticSearch这类成熟的搜索引擎,但ElasticSearch是需要单独部署的,显然不适合我的小型博客类项目;第二种途径是使用社区的一些全文索引的库,可以直接整合到自己的项目里,这是我的待定途径,如果Algolia不满足要求我便会用这种方法;第三种途径便是接入Algolia这类第三方的搜索引擎服务提供商,我们只需要这项目里封装Algolia提供的Api,再文章处理时适时的构建、更新或者删除索引即可。

Algolia的计划对比

这里只列出几个比较重要的

特点免费计划收费计划(Grow/Premium)
搜索API✔️✔️
预构建的UI库✔️✔️
搜索分析✔️✔️
每个用户的最大应用数1个不限
每个应用的最大索引数10个50个/1000个
索引大小限制1GB100GB
应用大小限制1GB100GB
每条记录的最大大小10KB10KB平均值,100KB最大值
每秒最大查询数(QPS)3不限
无活动停用限制(Inactivity Limit)30天无活动停用无限制

总结就是免费计划对我来说完全够用了,现阶段使用algolia挺不错的

如何使用Algolia

注册账号、获取appID、apiKey

之前看到的教程说Algolia需要申请资格什么的,我在实际操作过程中完全没有看到这个,可能时最近取消了资格要求吧

  1. 注册或登录账号Sign in | Algolia

    我是使用的GitHub账号登录注册的

  2. 创建应用

    第一次进入可能是他的Get Start页面,直接无视,你的任务只有一个那就是创建应用,左下角SettingApplicationsCreate Application,起个名字,选择Free计划再Next Step

    这时候我们进入了选择数据中心位置的页面,灰色的都是要收费的,我这里选择US West节点

    选择数据中心

    选好,下一步,勾选I agree ...Create Application,OK,你已经快完成了。

  3. 选择左上OverviewApi Keys,这时候你应该就可以查看跟复制你的appID与apiKey了,注意它们的用途。

    找到API key

    注意功能

后端处理

Algolia提供了大量的api接口和SDK非常方便你在项目中引入(如果你是hexo、hugo、vuePress这类已经整合了algolia或又相关插件的,那么上一步获取到appid和apiKey就已经可以去使用了)

有教程说使用docsearch-scraper来直接爬取数据的,我感觉多少有点小题大作了,既然都能部署docsearch-scraper了,那完全可以去部署个ElasticSearch来实现全文搜索了,这与使用algolia的初衷多少是有些违背的

丰富的api

我这里以go语言为例,演示一下后端应该有的逻辑

首先我们要导入Algolia的Go的sdk, 这提供了很多方法让我们操作索引

go get github.com/algolia/algoliasearch-client-go/v3

我的项目需要检索的数据就是我的文章,需要对标题和文章内容来构建索引,那么我们提交给Algolia的数据结构应该是这样的

GoLang
type artObject struct {
 ObjectID string // 必须的,这是algolia每一条记录的唯一标识
 ID      int    // 文章的id,这里主要是用于前端来访问到文章页面
 Cid     int    // 文章分类的id,可以使得前端获取到分类的信息
 Title   string // 标题
 Content string // 内容
}

我们创建一个方法来获取索引实例

GoLang
// NewEngine 获取一个搜索引擎的实例
func NewEngine(AppID, ApiKey, IndexName string) (*SearchEngine, error) {
 se := new(SearchEngine)

 se.ApiKey = ApiKey
 se.IndexName = IndexName
 se.AppID = AppID

 client := search.NewClient(AppID, ApiKey)
    //IndexName是可以随便取得,如果不存在就会自动创建
 index := client.InitIndex(IndexName)

    // 我们只需要index对象
 se.Index = index

 // 检查连接是否成功
 _, err := index.Exists()

 return se, err
}

为了获得更好得搜索效果,我们还需要对索引的设置项进行初始化

GoLang
// InitEngine 初始化引擎,主要是进行设置项的初始化,一般只需要执行一次
func (se *SearchEngine) InitEngine() error {
 index := se.Index

 if _, err := index.SetSettings(search.Settings{
        // 设置检索的条目
  SearchableAttributes: opt.SearchableAttributes(
   "content", "title",
  ),
        // 设置结果的排序依据
  Ranking: opt.Ranking(
   "desc(id)",
   "typo",
   "geo",
   "words",
   "filters",
   "proximity",
   "attribute",
   "exact",
   "custom",
  ),
  // 清空highlight(因为我们不需要这部分数据)
  AttributesToHighlight: opt.AttributesToHighlight(),

  // 设置简写,优化性能(返回经过简化处理的文章,截取命中关键词的那串文本)
  AttributesToSnippet: opt.AttributesToSnippet(
   "content:60",
   "title:30",
  ),

  // 取消content优化性能(不返回完整的文章内容)
  AttributesToRetrieve: opt.AttributesToRetrieve(
   "title",
   "id",
   "cid",
  ),
 }); err != nil {
  return logError(err)
 }
 return nil
}

写一个新建索引的方法, 删除等也是同理

GoLang
// SaveArts 构建文章的索引
func (se *SearchEngine) SaveArts(arts ...SearchArt) error {
 index := se.Index
 var objs []artObject

 for _, v := range arts {
  var obj artObject
  obj.ObjectID = "art" + strconv.Itoa(v.ID)
  obj.SearchArt = v

  objs = append(objs, obj)
 }

 if _, err := index.SaveObjects(objs); err != nil {
  return logError(err)
 }

 return nil
}

最后我们要在发布文章、修改文章、删除文章等需要对索引进行操作的位置引入方法。这样我们后端的逻辑就基本完成了。

前端处理

前端是最容易的,因为Algolia提供了几个现成的ui组件,我们直接按照教程在前端页面引入即可,这里同样也需要填写appID、apiKey与IndexName,注意这里的apiKey是search apiKey千万不要把你的admin apikey暴露给前端了。官方的InstantSearch.js、与autocomplete都挺不错的,也有官方的示例来方便你使用。

我的项目前端是对InstantSearch.js进行了简单的封装,让它lazyload了,后面我也会谈谈前端lazyload的一些方法。

总结

Algolia给小型项目提供了一个很好的搜索解决办法,虽然数据中心节点在海外但我的使用体验还是非常好的,结果基本都是秒出。

评论
正在加载评论组件...