12/08/2018, 10:49

Tìm kiếm nội dung tài liệu bằng máy tìm kiếm ElasticSearch

Từ trước đến nay chúng ta đã quá quen với các câu lệnh truy vấn với các Table trong các hệ cơ sở dữ liệu mysql, sqlite, postgres,...vv. Thế đã bao giờ bạn phải truy vấn một từ khóa dựa trên nội dung của một tài liệu bất kỳ mà bạn có chưa, có thể là file pdf, word, excel,......vv. Với những file ...

Từ trước đến nay chúng ta đã quá quen với các câu lệnh truy vấn với các Table trong các hệ cơ sở dữ liệu mysql, sqlite, postgres,...vv. Thế đã bao giờ bạn phải truy vấn một từ khóa dựa trên nội dung của một tài liệu bất kỳ mà bạn có chưa, có thể là file pdf, word, excel,......vv.

Với những file mà bạn có, nội dung không phải được lưu trong các Table, vậy thì làm thế nào mà bạn có thể tìm kiếm dựa trên từ khóa mà bạn nhập vào.

Để làm được việc này, thì bạn phải làm các bước như sau:

  1. Trước tiên bạn phải đọc vào một file mà bạn muốn tiến hành tìm kiếm
  2. Từ nội dung đọc vào, các từ sẽ được tách ra và đánh index, tiến hành lưu tạm vào một mảng
  3. Nhập vào từ khóa bạn muốn tìm kiếm
  4. Từ khóa được truy vấn trên mảng vừa tạo và đưa ra kết quả

Chúng ta có thể tự viết hàm cho tất cả các công việc trên nếu chịu khó bỏ thời gian và công sức. Nhưng với bộ máy tìm kiếm elasticsearch chúng ta có thể làm được tất cả các việc này.

**Cách cài đặt elastisearch ** Truy cập vào địa chỉ https://www.elastic.co/downloads/elasticsearch để download gói cài đặt, phiên bản hiện tại là elasticsearch-1.7.0 Giải nén sau khi download xong rồi cho vào một thư mục riêng, chẳng hạn ElasticSearch Tìm đường dẫn đến thư mục ElasticSearch/elasticsearch-1.7.0 chạy lệnh để cài đặt

bin/plugin install elasticsearch/elasticsearch-mapper-attachments/2.7.0

Như vậy là bạn đã cài đặt xong máy tìm kiếm elasticsearh Để kiểm tra việc cài đặt bạn vào thư mục ElasticSearch/elasticsearch-1.7.0/bin mà bạn đã cài đặt và chạy server elasticsearch bằng lệnh

./elasticsearch

Kết quả khi chạy thành công anh 1.png Có một thủ thuật nhỏ để bạn có thể chạy sever elasticsearch bất kỳ đâu mà không cần phải vào thư mục bin: đó là bạn mở file ẩn .bashrc lên và paste vào dòng lệnh ở cuối nội dung file export PATH="$HOME/ElasticSearch/elasticsearch-1.7.0/bin:$PATH" Và bây giờ bạn có thể ở bất kỳ thư mục nào trong máy tính và khởi động elasticsearch bằng câu lệnh

elasticsearch

Xây một ứng dụng nho nhỏ trên rails

Tiếp theo, chúng ta sẽ xây dựng một chức năng tìm kiếm nội dung file trên rails để kiểm chứng khản năng của elasticsearch. Giữa elasticsearch và rails chưa có một mối quan hệ nào (hay có thể nói là chưa thể giao tiếp với nhau), chính vì vậy chúng ta phải cài thêm gem "tire" Để upload file bạn muốn tìm kiếm thì bạn cũng cần gem "carrierwave" Cuối cùng là chạy lệnh

bundle install

Tạo thư mục document chứa file sẽ upload lên

rails g uploader DocumentAttachment

Tạo model chứa file

rails g model document title:string document_attachment:string

Upload file bất kỳ vào bảng Document, ví dụ 2 file test_1.pdf và test_2.pdf chẳng hạn

Document.create(title: "test_1", document_attachment: File.open('home/hoabattu/test_1.pdf'))
Document.create(title: "test_2", document_attachment: File.open('home/hoabattu/test_2.pdf'))

Trong file document.rb

class Document < ActiveRecord::Base
  # We're mounting the uploader the document_attachment attribute.
  # This attribute will store the path to the attachment.
  mount_uploader :document_attachment, DocumentAttachmentUploader

  # Setting up ElasticSearch integration
  include Tire::Model::Search
  include Tire::Model::Callbacks

  mapping _source: { excludes: ['attachment'] } do
    indexes :id, type: 'integer'
    indexes :title
    indexes :attachment, type: 'attachment'
  end

  def attachment
    path_to_attachment = document_attachment.file.file
    Base64.encode64(open(path_to_attachment) { |file| file.read })
  end

  def to_indexed_json
    to_json(methods: [:attachment])
  end
end

Tạo controller search

rails g controller search

Trong file search_controller.rb

class SearchController < ApplicationController
    def search
      if params[:q].nil?
        @documents = []
      else
        @documents = Document.search params[:q]
      end
    end

    def self.search(query)
      __elasticsearch__.search(
        {
          query: {
            multi_match: {
              query: query,
              fields: ['title^10', 'text']
            }
          },
          highlight: {
            pre_tags: ['<em>'],
            post_tags: ['</em>'],
            fields: {
              title: {},
              text: {}
            }
          }
        }
      )
    end
end

Tạo mới một file ở app/views/search/search.html.erb

<h1>Documents 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>
  <% @documents.each do |document| %>
    <li>
      <h3>
        <%= document.title %>
      </h3>
    </li>
  <% end %>
</ul>

Thêm vào file app/assets/stylesheets/search.css.scss

em {
  background: yellow;
}

Cấu hình file config/routes.rb

get "search", to: "search#search"

Chạy ứng dụng và xem kết quả Bây giờ bạn có thể vào đường dẫn http://localhost:3000/search và tiến hành tìm kiếm nội dung dựa trên 2 file test_1.pdf và test_2.pdf, ở đây tôi có sử dụng thêm file text_file.txt Screenshot from 2015-07-27 10:22:29.png

0