12/08/2018, 11:52

Elasticsearch- Full-text Seach

Elasticsearch làm những gì? Elasticsearch giống như 1 database lưu trữ tài liệu theo 1 cách "crafty", và có thể hỗ trợ cho người dùng tìm kiếm nhanh trên 1 file lớn. Để bắt đầu, Elasticsearch đánh indexs từ theo các thuật toán khác nhau. Elasticsearch không quan tâm đến các từ chung như "is" hay ...

Elasticsearch làm những gì?

Elasticsearch giống như 1 database lưu trữ tài liệu theo 1 cách "crafty", và có thể hỗ trợ cho người dùng tìm kiếm nhanh trên 1 file lớn. Để bắt đầu, Elasticsearch đánh indexs từ theo các thuật toán khác nhau. Elasticsearch không quan tâm đến các từ chung như "is" hay "to" khi trả về kết quả. Hay khi search từ khóa "looked" sẽ trả về các kết quả có bao gồm "looks" và looking".
Kết quả trả về sẽ là các kết quả phù hợp nhất đến ít nhất. Giả sử bạn muốn hỏi 1 câu hỏi : "what document best match the phrase: "holy guacamole , batman'?"
Nếu cụm từ mong muốn không thể tìm thấy, full-text search sẽ trả về các tài liệu có kết quả tốt nhất như "holy smokes,batman!" và "holy armadillo,batman" .

Full text search

Đây chính là phần core rất quan trọng của Elasticsearch. Chúng ta cùng xem làm thế nào Elasticsearch tìm kiếm với 1 ví dụ nhỏ

Index some data

Đầu tiên, chúng ta sẽ tạo ra 1 index mới và đánh index các tài liệu sử dụng bulk API( bulk api cho phép chúng ta tạo nhiều request cho " create, index, update,dElasticsearchete " trong 1 step.)

DELETE /my_index

PUT /my_index
{ "settings": { "number_of_shards": 1 }}

POST /my_index/my_type/_bulk
{ "index": { "_id": 1 }}
{ "title": "The quick brown fox" }
{ "index": { "_id": 2 }}
{ "title": "The quick brown fox jumps over the lazy dog" }
{ "index": { "_id": 3 }}
{ "title": "The quick brown fox jumps over the quick dog" }
{ "index": { "_id": 4 }}
{ "title": "Brown fox brown dog" }
  1. Bỏ index nếu nó tồn tại
  2. Chúng ta sẽ cùng tìm hiểu kĩ hơn tại sao tôi tạo 1 index duy nhất

Query with a single word

Trong ví dụ đầu tiên tôi sẽ giải thích điều gì xảy ra khi tôi sử dụng query để tìm kiếm 1 từ trong 1 tài liệu

GET /my_index/my_type/_search
{
    "query": {
        "match": {
            "title": "QUICK!"
        }
    }
}

Elasticsearch sẽ sử dụng câu truy vấn như sau:
1.Kiểm tra kiểu field
2.Phân tích chuỗi truy vấn
Chúng ta sẽ tìm kiếm với từ khóa Quick. Kêt quả sẽ chỉ trong liên quan đến quick . Bởii vì chúng ta chỉ có 1 nhóm duy nhất và câu truy vấn chỉ thực hiện 1 single low-level query. 3.Tìm kiếm trong tài liệu
Câu query sẽ xem "quick" trong số các index được đánh trong số danh sách các tài liệu. Trong trường hợp này nhóm của chúng ta sẽ là "1,2,3"
4.Độ chính xác của mỗi tài liệu
Elasticsearch sẽ tính toán và cho "điểm" cho mỗi tài liệu( xác định xem tài liệu nào có kqua tìm kiếm chính xác hơn). ( Elasticsearch sử dụng các thuật toán riêng để làm điều này, tôi sẽ giải thích thêm về các thuật toán đánh index của Elasticsearch trong bài khác)
-> đây là kết quả trọng số chúng ta thu được

"hits": [
 {
    "_id":      "1",
    "_score":   0.5,
    "_source": {
       "title": "The quick brown fox"
    }
 },
 {
    "_id":      "3",
    "_score":   0.44194174,
    "_source": {
       "title": "The quick brown fox jumps over the quick dog"
    }
 },
 {
    "_id":      "2",
    "_score":   0.3125,
    "_source": {
       "title": "The quick brown fox jumps over the lazy dog"
    }
 }
]

Các bạn có thể thấy 1 có score cao nhất bởi vì title ngắn nhất. Nó có nghĩa là kết quả liên quan đến độ lơn của nội dụng đc đề cập.
2.3 : 2 đc đánh score lớn hơn bởi vì quick đc nhắc đến 2 lần trong 2.

MULTIWORD

Nếu chúng ta chỉ thực hiện truy vấn 1 từ mỗi lần, Elasticsearch sẽ cho kết quả tuyệt vời. Vậy với multiword query , Elasticsearch có hiệu năng thế nào?

GET /my_index/my_type/_search
{
    "query": {
        "match": {
            "title": "BROWN DOG!"
        }
    }
}

Với câu seach trên ta sẽ thu được về cả 4 docs trong list kết quả.
1 dc score cao nhất boi vi từ kháa được lặp lại 1 lần và brown được lặp lại thêm 1 lần
2-3 same score bởi vì có cùng độ dài và số từ khóa đc nhắc đến
4 min bởi vì duy nhất brown đc nhắc đến .

Do câu query sử dụng tìm kiếm 2 terms : brown , dog. Elactic sẽ nhóm 2 tẻm queries trong 1 bool query ( tham khảo thêm tại Combinning queries)

Controlling Percision

Để lựa chọn được kết quả chính xác cũng giống như lựa chọn back hoặc white. Sẽ làm gì khi user đưa ra 5 query term và chỉ có 1 tài liệu chứa 4 trong số đó? Việc cài đặt "operator" to "and" sẽ thực hiện yêu cầu này của bạn
Đôi khi nó chính là điều bạn muốn. Nhưng phần lớn trong các trường hợp sử dụng full text search, bạn muốn thêm vào lựa chọn thích hợp để cho được kết quả chính xác (mong muốn)
Elastic hỗ chợ minimum_should_match parameter, cho phép bạn chỉ ra số terms sẽ so sánh trong tài liệu chứa các kết quả thích hợp .

GET /my_index/my_type/_search
{
  "query": {
    "match": {
      "title": {
        "query":                "quick brown dog",
        "minimum_should_match": "75%"
      }
    }
  }
}

Combining Queries

GET /my_index/my_type/_search
{
  "query": {
    "bool": {
      "must":     { "match": { "title": "quick" }},
      "must_not": { "match": { "title": "lazy"  }},
      "should": [
                  { "match": { "title": "brown" }},
                  { "match": { "title": "dog"   }}
      ]
    }
  }
}

Việc tính toán "score" cho mỗi term sẽ phụ thuộc vào "must" và "should"
"must not" sẽ không ảnh hương đến score, nó chỉ sử dụng để loại bỏ các từ đc thêm vào.

Controlling Analysis

Queries có thể tìm chính xác kết quả ( theo index được đánh) điều này rất quan trong để chắc kêt quả phân tích được áp dụng đúng trong tất cả các tài liệu đc đánh index. Tuy thế khi phân tích document, mỗi filed có thể 1 cách phân tích khác nhau, và ta có thể cấu hình tùy chọn cho mỗi riêng từng tài liệu
Đi đến với exam: add vào 1 filed mới : my_index.

PUT /my_index/_mapping/my_type
{
    "my_type": {
        "properties": {
            "english_title": {
                "type":     "string",
                "analyzer": "english"
            }
        }
    }
}

Ok. Chúng ta sẽ đi so sanh làm thế nào giá trị của english_title và title được phân tích bằng cách sử dụng analyze api để phân tích từ "foxes"

GET /my_index/_analyze?field=my_type.title
Foxes

GET /my_index/_analyze?field=my_type.english_title
Fox
  1. Field title no được sử dụng mặc định " standard" analyzer, và nó sẽ trả về term : foxer.
  2. Field english_title nó được sử dụng "english" analyzer , sẽ trả về term là : fox.

Điều này nghĩa là với các kiểu phân tích khác nhau , chúng ta sẽ thu được các kết quả khác nhau. Việc lựa chọn và cấu hình các thuật toán cho việc phân tích "full text search" rất quan trọng, nó quyết định đến kết quả bạn nhận được có phải là kết quả bạn mong muốn nhận được không.
Trong một bài viết tiếp tôi sẽ giới thiệu thêm về các key word được sử dụng cho phân tích tài liệu được sử dụng trong elastic.
Tài liệu sử dụng https://www.elastic.co/guide/en/elasticsearch/guide/current/match-multi-word.html

0