为博客添加 Algolia 搜索
原先我是使用 pg_search 包做搜索功能,但搜索效果很差,由于没有安装中文分词库,所以模糊搜索几乎不可用。
所以我想优化搜索功能,刚开始是准备自部署 meilisearch 服务端来完成,初始代码写完后,却一直无法完成 ActionText 的索引,遂放弃。
随后简单对比了几家提供搜索功能的服务商,只有 Algolia 提供了免费层,1万次/月的搜索次数,1百万条索引记录,非常慷慨,而且它也是 Hacker News 的全文搜索后端,很好用。
Algolia 支持的数据导入方式非常丰富,除了 api 外,还提供了主流 CMS 的插件、爬虫、文件的导入方法:
algolia import data methods
这里我使用了 Rails 的SDK进行导入,步骤如下:
1. 添加包到 Gemfile 并安装
所以我想优化搜索功能,刚开始是准备自部署 meilisearch 服务端来完成,初始代码写完后,却一直无法完成 ActionText 的索引,遂放弃。
随后简单对比了几家提供搜索功能的服务商,只有 Algolia 提供了免费层,1万次/月的搜索次数,1百万条索引记录,非常慷慨,而且它也是 Hacker News 的全文搜索后端,很好用。
Algolia 支持的数据导入方式非常丰富,除了 api 外,还提供了主流 CMS 的插件、爬虫、文件的导入方法:

这里我使用了 Rails 的SDK进行导入,步骤如下:
1. 添加包到 Gemfile 并安装
gem "algoliasearch-rails"
2. 添加初始化文件:config/initializers/algoliasearch.rb
AlgoliaSearch.configuration = { application_id: ENV["ALGOLIASEARCH_APP_ID"], api_key: ENV["ALGOLIASEARCH_API_KEY"], # pagination_backend: :will_paginate # 如果使用了 will_paginate 分页,可添加该行 }
3. 在需要索引的模型中,添加搜索功能,比如我在 Article 模型中添加的代码:
class Article < ApplicationRecord has_rich_text :content # ... include AlgoliaSearch algoliasearch if: :should_index? do attribute :title, :slug, :description, :plain_content attribute :plain_content do text = content.to_plain_text algolia_max_characters = ENV.fetch("ALGOLIA_MAX_CHARACTERS", "3500").to_i if text.size > algolia_max_characters text = text.truncate(algolia_max_characters) end text end searchableAttributes [ "title", "slug", "description", "plain_content" ] end def should_index? status == "publish" || status == "shared" end #... end
需要注意的是,免费层的每个索引记录大小需要限制在 10kb 以内,但我使用 bytesize 方法时无法成功添加,提示无效的 object,所以这里我直接使用字符数。
然后在 articles_controller 中添加相关处理代码
然后在 articles_controller 中添加相关处理代码
def index respond_to do |format| format.html { @page = params[:page].present? ? params[:page].to_i : 1 @per_page = 10 if params[:q].present? # 使用Algolia搜索 algolia_results = Article.algolia_search(params[:q], { hitsPerPage: @per_page, page: @page - 1 }) # Algolia页码从0开始 # 获取Algolia的结果总数 @total_count = algolia_results.size @articles = algolia_results else # 不搜索,只分页 @articles = Article.published .includes(:rich_text_content) .order(created_at: :desc) .paginate(page: @page, per_page: @per_page) @total_count = @articles.total_entries end } # ... end end
在 view 中添加搜索代码
<%= form_tag root_path, method: :get, class: 'search-form' do %> <%= search_field_tag :q, params[:q], placeholder: 'Search...' %> <%= submit_tag 'Search' %> <% end %>
最后,设置好认证信息和环境变量后,在 rails console 中进行首次索引:Article.reindex!
如果想清除所有索引,则执行:Article.clear_index!
完成
完成