12/08/2018, 13:30

SỬ DỤNG ELASTICSEARCH TRONG RAILS VỚI GEM SEARCHKICK

I. Cài đặt Elasticsearch sudo apt-get update sudo apt-get install elasticsearch start và restart lại server ES bằng lệnh sudo service elasticsearch start sudo service elasticsearch restart II. Cài đặt gem searchkick Thêm searchkick vào gem file gem “searchkick&rd ...

I. Cài đặt Elasticsearch

    sudo apt-get update
    sudo apt-get install elasticsearch

start và restart lại server ES bằng lệnh

    sudo service elasticsearch start
    sudo service elasticsearch restart

II. Cài đặt gem searchkick

Thêm searchkick vào gem file

gem “searchkick”

Sau đó chạy:

bundle install

III. Tích hợp Elasticsearch với rails app

Tạo 1 rails app với model Product có trường name: string

rails generate scaffold Product name:string

Thêm module searchkick vào model Product models/product.rb

class Product < ActiveRecord::Base
  searchkick
end

Để index dữ liệu của Product lên server ES ta dùng lệnh:

Product.reindex

Gọi hàm search từ controller.

controllers/products_controller.rb

class ProductsController < ApplicationController
  def index
    if params[:query].present?
      @products = Product.search params[:query]
    else
      @products = Product.all
    end
  end
end

Thêm form search trong view

views/products/index.html.erb

<div>
  <%= form_tag "/products", method: :get, class: "form-inline" do %>
    <%= text_field_tag "query", params[:query], class: "form-control" %>
    <%= submit_tag "Search" %>
  <% end %>
</div>

product1.png

IV. Thêm tính năng Autocomplete

Thêm autocomplte vào module searchkick trong model Product

class Product < ActiveRecord::Base
  searchkick autocomplete: [“name”]
end

Sau khi thêm sẽ reindex model Product

Product.reindex

Thêm function autocomplete vào controller

def autocomplete
  render json: Product.search(params[:term], {
    fields: ["name"],
    limit: 10
    }).map(&:name)
end

Sửa file routes config/routes.rb

resources :products do
  collection do
    get :autocomplete
  end
end

thêm tính năng autocomplete vào layout

<%= stylesheet_link_tag "//code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css" %>
<%= javascript_include_tag "//code.jquery.com/ui/1.11.2/jquery-ui.js" %>

Sửa form search

<%= form_tag "/products", method: :get, class: "form-inline" do %>
  <%= text_field_tag "query", params[:query], class: "form-control", id: "product_search", autocomplete: "off" %></br>
  <%= submit_tag "Search" %>
<% end %>

Thêm javascript gọi autocomple

<script>
  $("#product_search").autocomplete({
    source: "/products/autocomplete.json",
    minLength: 2
  });
</script>

product_2.png

V. Thêm tính năng suggestions

Thêm vào module searchkick trong model Product

class Product < ActiveRecord::Base
  searchkick  suggest: [:name]
end

Sau đó reindex

Product.reindex

Sửa hàm search trong controller

@products = Product.search params[:query], suggest: true

Thêm từ được suggest vào view

<div>
  <% if @products.suggestions.present? %>
    <%= @products.suggestions %>
  <% end %>
</div>

product_3.png

VI. Thêm chức năng Highlight

Thêm vào module searchkick trong model Product

class Product < ActiveRecord::Base
  searchkick  highlight: [:name]
end

Sau đó reindex lại.

Product.reindex

Sửa hàm search trong controller

@products = Product.search params[:query], fields: [:name], highlight: true

Hiển thị highlight trong view.

<% if @products.try(:with_details).present? %>
  <% @products.with_details.each do |product, details| %>
    <tr>
      <td><%= details[:highlight][:name] %></td>
      <td><%= link_to 'Show', product %></td>
      <td><%= link_to 'Edit', edit_product_path(product) %></td>
      <td><%= link_to 'Destroy', product, method: :delete, data: { confirm: 'Are you sure?' } %></td>
    </tr>
  <% end %>
<% else %>
  <% @products.each do |product| %>
    <tr>
      <td><%= product.name %></td>
      <td><%= link_to 'Show', product %></td>
      <td><%= link_to 'Edit', edit_product_path(product) %></td>
      <td><%= link_to 'Destroy', product, method: :delete, data: { confirm: 'Are you sure?' } %></td>
    </tr>
  <% end %>
<% end %>

product_4.png

VII.

0