在實(shí)際應(yīng)用中如果可以讓用戶快速的搜索出自己想要的內(nèi)容剧蹂,這將會是一個很有用的功能功炮。那么要怎么來實(shí)現(xiàn)呢?
像簡單一點(diǎn)的方法可以使用 SQL 的 LIKE
來實(shí)現(xiàn)题造,如
SELECT * FROM articles WHERE title LIKE '%小蘋果%';
但這樣實(shí)現(xiàn)對數(shù)據(jù)量很大的表鹦赎,其實(shí)是相當(dāng)耗時的谍椅。而且在其它業(yè)務(wù)下,我們可以會對用戶提交的搜索詞古话,進(jìn)行分詞雏吭。在分詞后,上面的SQL 可能就變成
SELECT * FROM articles WHERE title ?LIKE '%小蘋果%' OR LIKE '%蘋果%' OR LIKE '%小%';
這樣效率肯定更低了陪踩。這時候我們可以使用 第三方的搜索程序杖们,來減少數(shù)據(jù)庫的壓力悉抵,像 elasticsearch
,Solr
等等胀莹。
我們這里選擇 elasticsearch
基跑,具體可以看這里 Elasticsearch 與 Solr
如果還不知道 elasticsearch婚温,請選 ElasticSearch 入門
安裝 Gem
Rails 下使用 ElasticSearch 描焰,可以使用 elasticsearch-rails 這個 Gem
# Gemfile
# 搜索
gem 'elasticsearch-model'
gem 'elasticsearch-rails'
$ bundle
配置 Model
打開要添加搜索的 model 類,添加如下內(nèi)容
# app/models/article.rb
+ require 'elasticsearch/model'
class Article < ActiveRecord::Base
...
+ include Elasticsearch::Model
+ include Elasticsearch::Model::Callbacks
+ settings index: { number_of_shards: 1 } do
+ mappings dynamic: 'false' do
+ indexes :title
+ end
+ end
...
end
+ # Delete the previous articles index in Elasticsearch
+ Article.__elasticsearch__.client.indices.delete index: Article.index_name rescue nil
+ # Create the new index with the new mapping
+ Article.__elasticsearch__.client.indices.create \\
+ index: Article.index_name,
+ body: { settings: Article.settings.to_hash, mappings: Article.mappings.to_hash }
+ # Index all article records from the DB to Elasticsearch
+ Article.import force: true
使用
添加 app/controllers/search_controller.rb
class SearchController < ApplicationController
def search
if params[:q].nil?
@result = []
else
@result = Article.search(params[:q]).paginate(page: 1, per_page: 10)
end
end
end
添加 ** app/views/search/search.html.erb**
<h1>Articles Search</h1>
<%= form_for search_path, method: :get do |f| %>
<p>
<%= f.label "Search for" %>
<%= text_field_tag :q, params[:q] %>
<%= submit_tag "Go", name: nil %>
</p>
<% end %>
<ul>
<% @result.records.each_with_hit do |item, hit| %>
<p><%= item.title %></p>
<% end %>
</ul>