12/08/2018, 13:06
Fulltext search với Solr - Phần 1 - Giới thiệu
Thời gian gần đây mình đang có hứng thú với fulltext search trong lập trình Rails - chắc hẳn các bạn cũng có nghe qua về chủ đề này Trước tiên mình xin lấy trích dẫn 1 chút định nghĩa về fulltext search trên wikipedia In a full-text search, a search engine examines all of the words ...
Thời gian gần đây mình đang có hứng thú với fulltext search trong lập trình Rails - chắc hẳn các bạn cũng có nghe qua về chủ đề này
Trước tiên mình xin lấy trích dẫn 1 chút định nghĩa về fulltext search trên wikipedia
In a full-text search, a search engine examines all of the words in every stored document as it tries to match search criteria for example
Có thể hiểu đơn giản là với fulltext search thì cỗ máy tìm kiếm sẽ cố gắng tìm kiếm dựa trên tất cả các từ có trong văn bản đã được lưu phù hợp với truy vấn
Và có 2 thư viện fulltext search rất tốt cho người lập trình Rails đó là
-
Elasticsearch
-
Sunspot
Bản chất của những thư viện này là khi làm việc thì nó sẽ xây dựng ra một bộ index để lưu tất cả các từ mà nó xử lý được từ trong nội dung văn bản. Khi tìm kiếm thì nó sẽ dựa vào bộ index này
Nó cũng gần giống với các xây dựng chỉ mục cho các cỗ máy phân tích trong bộ môn xử lý ngôn ngữ tự nhiên ngày trước mình từng học ở đại học (đây cũng là lý do khiến mình có hứng thú với fulltext search)
Nếu muốn tìm hiểu về Elasticsearch thì bạn có thể xem một số bài viết về chủ đề này hoặc là Google thần chưởng =)). Trong loạt bài viết này, mình xin được đề cập đến Solr với thư viện Sunspot để lập trình fulltext search trong Rails
Phần 1: Giới thiệu Sunspot
** 1. Giới thiệu**
Solr là 1 nền tảng tìm kiếm chuyên nghiệp, mã nguồn mở và được xây dựng bằng ngôn ngữ Java trên Apache Lucene. Nó rất phổ biến và có tốc độ xử lý nhanh. Nếu bạn muốn tìm hiểu kỹ hơn về Solr thì có thể tham khảo ở đây
Thư viện sunspot được xây dựng để làm việc với Rails và đã được đẩy lên Github. Bạn có thể tìm hiểu cụ thể hơn tại đây
Mặc định thì sunspot sử dụng cấu hình khá là bảo thủ cho fulltext search. Văn bản sẽ được chia ra thành các thẻ dựa trên dấu cách và các ký tự khác (bằng cách sử dụng một tokenizer thông minh được gọi là StandardTokenizer)
Solr cực kỳ linh hoạt trong cách lập chỉ mục và tìm kiếm toàn văn bản; rất nhiều chức năng tiên tiến có thể được cấu hình khá dễ dàng
** 2. Cài đặt**
Với 1 project sẵn có, việc cài đặt sunspot là cực kỳ đơn giản
-
Thêm vào Gemfile 2 dòng sau và tiến hành bundle install
gem "sunspot_rails" gem "sunspot_solr"
-
Khi 2 gem trên đã được cài đặt, chúng ta sẽ phải tạo ra file cấu hình mặc định bằng dòng lệnh:
rails generate sunspot_rails:install
-
Bước cuối cùng để hoàn thành việc cài đặt sunspot cho project là start server solr:
bundle exec rake sunspot:solr:start
Câu lệnh này cũng đồng thời tạo ra thư mục /solr ngay trong thư mục gốc của project
Và có 1 file cực kỳ quan trọng là solr/configsets/sunspot/conf/schema.xml (ở một số phiên bản khác nhau thì cấu trúc thư mục này có thể khác nhau đôi chút) để chứa các thông tin cấu hình cho hoạt động của hệ thống tìm kiếm. Bạn có thể thay đổi file cấu hình này. Nhưng phần này mình xin được đề cập cụ thể hơn ở các bài viết sau (bowbowbow)
-
Khi bạn muốn solr thực hiện lại việc đánh chỉ mục cho dữ liệu cả bạn thì dùng lệnh :
bundle exec rake sunspot:reindex
-
Nếu xảy ra lỗi khi khởi động server solr, bạn có thể sử dụng câu lệnh sau :
bundle exec rake sunspot:solr:run
Một lưu ý nhỏ của mình là nên thêm thư mục solr/data vào trong .gitignore trong quá trình làm việc với sunspot
Đến đây là bạn đã có thể tiến hành lập trình và sử dụng fulltext search cho project của mình được rồi. Phần tiếp theo mình sẽ có một demo nhỏ để các bước đầu làm quen với sunspot
** 3. Demo **
-
Demo của mình chỉ đơn giản chỉ có bảng posts với 2 trường :
t.string :title t.string :body - #### Và một chút cấu hình nhỏ cho việc **fulltext search** trong `searchable` cho model `Post` như sau : ```ruby class Post < ActiveRecord::Base searchable do text :title, default_boost: 2 text :body end end #### `default_boost: 2` ở đây hiểu đơn giản có nghĩa là `title` sẽ được ưu tiên tìm kiếm hơn so với `body` gấp `2` lần - #### Xây dựng method `search` trong `PostController`: ```Ruby class PostController < ApplicationController def search @search = Post.search(include: [:comments]) do keywords(params[:q]) end end end
-
Thêm router
get "search", to: "post#search"
-
Và cuối cùng là view app/views/post/search.html.erb
<!--Form search--> <%= 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 %> <% @search.each_hit_with_result do |hit, post| %> <h2><%= h post.title %></h2> <h4>(<%= h hit.score %>)</h4> <p><%= h truncate(post.body, length: 100) %></p> <% end %>
-
Cuối cùng là bạn có thể vào link http://localhost:3000/search để xem kết quả. Ở đây của mình có như sau :
-
Source code của demo mình để ở đây.
** Tham khảo **
- ####http://lucene.apache.org/solr
- ####https://github.com/sunspot/sunspot
- ####https://github.com/sunspot/sunspot/wiki