Elasticsearch search attachment
Elasticsearch
5
White

Lê Minh Tuấn viết ngày 25/07/2015

alt text

1. Elasticsearch là gì ???

2. ElasticSearch dùng cho những ứng dụng nào ???

3. Vấn đề :

  • Hiện nay tất cả các hệ thống thông tin (hay cụ thể là mỗi website, service ....) đều cung cấp cho user một chức năng tìm kiếm nội dung trong hệ thống của họ, rất nhiều hệ thống cho phép user upload một file lên hệ thống của họ vậy một câu hỏi đặt ra là:
  • "tôi sẽ gửi lên một từ khóa và hệ thống có thể tìm kiếm từ khóa đó trong nội dung những file được upload , ý tôi là tôi không tìm theo tên file hay tên tác giả mà thôi tìm theo nội dung file"
  • Ví dụ :
    • bình thường vào một trang web nghe nhạc tôi có thể nhập từ khóa để tìm kiếm tên bài hát, tên ca sĩ nhưng có cách nào để tôi tìm kiếm theo nội dung bài hát.
    • Khi search một cái email đã gửi nhưng tôi quên mất tiêu đề của email, mà chỉ nhớ nội dung file mà tôi đã attach vào email, vậy có cách nào để tôi tìm kiếm theo nội dung của file đã attach.

Hôm nay em sẽ xin giải đáp những câu hỏi đó dựa vào ElastichSearch

Let's get started.

Tham khảo :

  • Chị Nguyễn Thị Ngọc xinh đẹp của công ty.
  • http://www.elasticsearch.cn/tutorials/2011/07/18/attachment-type-in-action.html
  • https://github.com/elastic/elasticsearch-mapper-attachments
  • #!/bin/sh
    host=localhost:9200
    curl -X DELETE "${host}/test"
    curl -X PUT "${host}/test" -d '{
    "settings" : { "index" : { "number_of_shards" : 1, "number_of_replicas" : 0 }}
    }'
    curl -X GET "${host}/_cluster/health?wait_for_status=green&pretty=1&timeout=5s"
    curl -X PUT "${host}/test/attachment/_mapping" -d '{
    "attachment" : {
    "properties" : {
    "file" : {
    "type" : "attachment",
    "fields" : {
    "title" : { "store" : "yes" },
    "file" : { "term_vector":"with_positions_offsets", "store":"yes" }
    }
    }
    }
    }
    }'
    curl -C - -O http://www.intersil.com/data/fn/fn6742.pdf
    coded=`cat fn6742.pdf | perl -MMIME::Base64 -ne 'print encode_base64($_)'`
    json="{\"file\":\"${coded}\"}"
    echo "$json" > json.file
    curl -X POST "${host}/test/attachment/" -d @json.file
    echo
    curl -XPOST "${host}/_refresh"
    curl "${host}/_search?pretty=true" -d '{
    "fields" : ["title"],
    "query" : {
    "query_string" : {
    "query" : "amplifier"
    }
    },
    "highlight" : {
    "fields" : {
    "file" : {}
    }
    }
    }'
    #
    # The following is output of the last search query:
    #
    #
    #
    #{
    # "took" : 6,
    # "timed_out" : false,
    # "_shards" : {
    # "total" : 1,
    # "successful" : 1,
    # "failed" : 0
    # },
    # "hits" : {
    # "total" : 1,
    # "max_score" : 0.005872132,
    # "hits" : [ {
    # "_index" : "test",
    # "_type" : "attachment",
    # "_id" : "UUaHJ6CfTOC3T2I4Kj_pXg",
    # "_score" : 0.005872132,
    # "fields" : {
    # "file.title" : "ISL99201"
    # },
    # "highlight" : {
    # "file" : [ "\nMono <em>Amplifier</em> • Filterless Class D with Efficiency > 86% at 400mW\nThe ISL99201 is a fully integrat", "\nmono <em>amplifier</em>. It is designed to maximize performance for \nmobile phone applications. The applicat" ]
    # }
    # } ]
    # }
    #}
    view raw gistfile1.js hosted with ❤ by GitHub
  • http://rny.io/rails/elasticsearch/2013/08/05/full-text-search-for-attachments-with-rails-and-elasticsearch.html
  • https://www.elastic.co/guide/en/elasticsearch/reference/1.3/mapping-attachment-type.html

1. Elasticsearch là gì.

2. ElasticSearch dùng cho những ứng dụng nào ???

  • ELASTIC-SEARCH có thể tích hợp được với tất cả các ứng dụng sử dụng các loại ngôn ngữ sau.
    • Java
    • JavaScript
    • Groovy
    • .NET
    • PHP
    • Perl
    • Python
    • Ruby

3. Giải quyết vấn đề "tìm kiếm theo nội dung file".

  • Mapper Attachments : là một plugin của Elasticsearch , cho phép tạo một type trong ES có tên là attachment.
  • Tương tự như ta có kiểu Integer, Datetime, String... thì attachment type đơn giản cũng chỉ là một kiểu dữ liệu mà có thể đánh index cho rất nhiều định đạng file khi đã được encode ở base64.
  • Chốt lại Mapper Attachments là một cái gì đó để cho phép tạo ra một kiểu dữ liệu tên là attachment, nếu String dùng để lưu một chuỗi kí tự thì kiểu dữ liệu attachment này để lưu nội dung một file và có thể đánh index cho nội dung một file. (file đó đã được convert sang base 64).

Các bước để sử dụng Mapper Attachments trong ES

Step 1: Cài đặt Mapper Attachments

  • Em cài ES 1.7 và elasticsearch-mapper-attachments-2.7.0 hai version này hoạt đọng tốt với nhau nên em recomment. link
 $ bin/plugin install elasticsearch/elasticsearch-mapper-attachments/2.7.0
  • Sau khi cài đặt thành công bạn sẽ thấy có một folder mới được them tại thư mục plugins có tên là mapper-attachments

alt text

Step 2: Khởi tạo một index mới có tên là test để chuẩn bị cho việc indexing data

  • Chắc chắn là anh chị đã mở server ES.

  • Chú ý :

    • Trong Elasticsearch khái niệm index tương ứng với database trong mysql (tạm hiểu vậy cho dễ hiểu ạ !!!).
    • Index <=> Database
    • Type <=> Table
    • Document <=> Record
    • Mapping <=> create field in a table
    • Làm ơn đừng nghĩ type trong Elasticsearch là một kiểu dữ liệu, mà nó tương đương với table
  • Create và Setting cho index test:

curl -X PUT "localhost:9200/test" -d '{
  "settings" : { "index" : { "number_of_shards" : 1, "number_of_replicas" : 0 }}
}'

Step 3: Khởi tạo một type mới có tên "document" và thực hiện mapping cho type này :

  • Việc thực hiện mapping chính là việc tạo ra các trường (field) trong một bảng (table)

  • Đoạn code bên dưới là để add them trường file có kiểu là attachment vào type document.

  • Như đã nói kiểu dữ liệuattachment là kiểu dữ liệu dùng để save các dữ liệu ở base64 (nội dung các file đã đc convert sang base64 )

Cách add thêm trường vào một Type (Table)

Cách 1:

curl -X PUT "localhost:9200/test/document/_mapping" -d '{
  "document" : {
    "properties" : {
      "file" : {
        "type" : "attachment",
        "fields" : {
          "title" : { "store" : "yes" },
          "file" : { "term_vector":"with_positions_offsets", "store":"yes" }
        }
      }
    }
  }
}'

Cách 2

curl -X PUT "localhost:9200/test/_mapping/document" -d '{
    "properties" : {
      "file" : {
        "type" : "attachment",
        "fields" : {
          "title" : { "store" : "yes" },
          "file" : { "term_vector":"with_positions_offsets", "store":"yes" }
        }
      }
  }
}'

Step 4: indexing data :

  • File gốc có thể là định dạng txt, pdf , doc, .... nhưng để indexing cho những file này ta phải convert sang base64

  • Conver sang base64

$ base64_coded=`cat abc.pdf | perl -MMIME::Base64 -ne 'print encode_base64($_)'`
  • Ghi mã base64 sang một file mới :
json="{\"file\":\"${base64_coded}\"}"
echo "$json" > json.file
  • lúc này ta nhận một file mới với nội dung đã encode là base64 có tên "json.file"

  • Indexing nội dung file này vào index test với type là attachment

  • json.file là một đoạn mã base64.

  • Insert vào bảng document trong database test với câu lệnh bên dưới :

$ curl -X POST "localhost:9200/test/document/" -d @json.file
  • Trong table document ta co một trường tên là file kiểu dữ liệu là attachment, khi ta thực hiện câu lệnh trên ta sẽ insert thêm một record mới vào bảng document và giá trị của trường file chính là mã code base64 của file đã convert.

alt text

Step 5 : Searching

  • Bây h ta sẽ search nội dung file theo một từ khóa
curl "localhost:9200/_search?pretty=true" -d '{
  "fields" : ["title"],
  "query" : {
    "query_string" : {
      "query" : "keyword"
    }
  },
  "highlight" : {
    "fields" : {
      "file" : {}
    }
  }
}'

Kết Quả :

  • Em tìm kiếm với từ khóa là "test" và kết quả hiển thị như bên dưới
  • Dẫ tìm thấy một từ "test" trong file abc.pdf của em aak.

alt text

Super simple command:

INDEX

  • Hiển thị toàn bộ index
    • curl 'localhost:9200/_cat/indices?v'
  • Xóa index
    • curl -XDELETE 'http://localhost:9200/twitter/'
  • Xóa toàn bộ index

    • curl -XDELETE 'http://localhost:9200/_all/'
  • Hiển thị mapping trong index ABC

    • curl -XGET 'http://localhost:9200/ABC/_mapping'

TYPE

  • List all Type của một Index, List all field của một Type
    • curl -XGET 'http://localhost:9200/ABC/_mapping?pretty' <=> Company.mappings.to_hash
  • Xóa một type
    • - curl -XDELETE 'http://localhost:9200/twitter/twee'

DOCUMENT

  • List all document(record) in the type

    • curl 'http://localhost:9200/documents/document/_search?pretty&fields=&_source='
  • Xóa 1 document
    curl -XDELETE 'http://localhost:9200/myindex/type/idl'

  • Xóa toàn bộ documents trong index company

    • curl -XDELETE 'http://localhost:9200/myindex/mytype/_all'
    • curl -XDELETE 'http://localhost:9200/mytype/_all'

Elasticsearch gem - Ruby client

A. Dump data:

  • Khi tạo mới một record trong DB thì elasticsearch gem sẽkhông tạo mới document trong ES servermà phải dùng lệnh import để dump data.

B. Callbacks

  • include Elasticsearch::Model::Callbacks : sẽ giải quyết vấn đề của phần A trên , nó sẽ đồng bộ hóa dữ liệu trong DB (mysql ) với dữ liệu trong ES. khi bạn create/destroy/update dữ liệu trong MySql bằng model thì TRong ES cũng được update theo.
  • Callbacks : Automatically update Elasticsearch index when the model changes

  • Sau khi CRUD ở DB xong thì gem này sẽ gị tới các after_save, after_update, after_delete
    và trong các hàm này sẽ gửi mội request tương ứng POST, PUT, DELETE lên ES server để cập nhật lại data ở ES sao cho chúng luôn đồng bộ với nhau,

    class Company < ActiveRecord::Base
    include Elasticsearch::Model
    include Elasticsearch::Model::Callbacks # Mục đích là tự động đồng bộ dữ liệu với ES khi ta CRUD ở DB (Mysql )
    end
    
  • Chú ý : Nếu ta xóa data ở ES trước và sau đó mới ra xóa record tương ứng ở DB (MySQL ) thì sẽ bị bung ra exception bởi vì bản chất của callbacks là sau khi xóa xong ở DB(mysql ) nó sẽ gọi đến hàm after_save để gửi mội POST request lên ES server để xóa đi document tương ứng.

    C. Indexing data

  • Elasticsearch mặc định sẽ đánh index cho tất cả các trường trong 1 document (nếu trường đó có giá trị khác nil)

  • Chỉ khi trường nào được đánh index thì ta mới có thể search theo trường đó : vì thế ta có thể định nghĩa các trường muốn đánh index như sau

class Company < ActiveRecord::Base
  include Elasticsearch::Model
  include Elasticsearch::Model::Callbacks

  # là hàm để định nghĩa ra các trường muốn đánh index (nghĩa là khi search thì sẽ search theo các trường đó)
  def as_indexed_json(options={})
    as_json only: [:name, :title]
  end
end

D. Mapping

  • Là cơ chế của ES nhắm mục đich : Định nghĩa ra những trường nào sẽ được đánh index (có thể search theo trường đó)
  • Mapping có thể hiểu nó tương tự như hàm as_indexed_json.
  • Khi dùng Mapping ta có thể tạo ra một trường (field) với một kiểu dữ liệu bất kì ("attachment", String, Integer) mà trường này chỉ tồn tại trên ES server, Không cần có phải tồn tại trên database (mysql)

E. Create Index from Model

  • Elastichsearch luôn ánh xạ một model trong rails thành :

    • Ví dụ ta có model là Company thì khi ánh xạ vào ES ta sẽ nhận được :
      • Một index có tên là : companies
      • Một Type của index companiescompany
    • Ví dụ ta có một index là Document thì khi ánh sạ vào ES ta sẽ thu được:
    • Một index có tên là: documents
    • Một type của index documents là document.

Thanks.

Đây là lần đầu em tìm hiểu về phần này, rất mong nhận đc ý kiến từ anh chị để em có thể sửa những phần em sai và chưa biết, (thankyou)

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Lê Minh Tuấn

11 bài viết.
23 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
15 2
1. Maven là gì? 2. Maven hoạt động như nào? 3. Tại Sao cần Maven? 4. Cài đặt Maven 5. Khởi tạo một Project Java bằng Maven 6. Cấu trúc POM.xml...
Lê Minh Tuấn viết 3 năm trước
15 2
White
13 5
1. Javascript FUNCTIONAL OR OBJECT ORIENTED? 2. JavaScript, object oriented? 3. Nodejs require exports vs module.exports 4. Referrence Trả lời: ...
Lê Minh Tuấn viết 2 năm trước
13 5
White
12 0
(Ảnh) 1. Software design pattern là gì ? 2. Có bắt buộc phải sử dụng design pattern khi lập trình ? 3. Có bao nhiêu design pattern ? 5. Bà...
Lê Minh Tuấn viết 3 năm trước
12 0
Bài viết liên quan
White
5 0
About elasticsearch memory control Elasticsearch rất dễ bị die bởi OOM(OutOfMemory) bởi memory trên ES được dùng intensive trong rất nhiều logic k...
huydx viết hơn 1 năm trước
5 0
White
55 9
Elasticsearch là gì (Ảnh) Elasticsearch chắc hẳn là nhiều người đã biết, nhưng để bài viết trơn tru, cứ phải có cái introduction cho nó dài. Elas...
huydx viết 12 tháng trước
55 9
White
10 0
Có cái note từ xưa hồi mới học ES nhét ở evernote, để lên đây cho khỏi mất Elasticsearch Document == row, grouped by types, multiple types == i...
huydx viết gần 2 năm trước
10 0
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
11 bài viết.
23 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!