12/08/2018, 12:21

Tìm kiếm với elasticsearch: cơ bản và nâng cao

Elastic search một search engine server có ưu thế về sự ổn định, tốc độ cao, dễ sử dụng và độc lập với các hệ quản trị cơ sở dữ liệu như SQL. Việc giao tiếp với Elastic server có thể được thực hiện dễ dàng thông qua giao thức http. Chỉ cần nắm được các câu lệnh truy vấn là có thể dễ dàng điều ...

Elastic search một search engine server có ưu thế về sự ổn định, tốc độ cao, dễ sử dụng và độc lập với các hệ quản trị cơ sở dữ liệu như SQL. Việc giao tiếp với Elastic server có thể được thực hiện dễ dàng thông qua giao thức http. Chỉ cần nắm được các câu lệnh truy vấn là có thể dễ dàng điều khiển, tìm kiếm hoặc thậm chí tự viết một API cho ngôn ngữ khác một cách dễ dàng.

Bài viết nhằm mục đích hướng dẫn sử dụng một số câu truy vấn từ cơ bản đến phức tạp của Elastic search. Mọi chí tiết có thể tham khảo trên trang doc chính thức của Elastic search: https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html

Match query

Ta bắt đầu với tìm kiếm đơn giản nhất: tìm kiếm bằng. Ví dụ muốn tìm id bằng 1, ta có hai cách:

  • Cách 1:
{
    "match" : {
        "id" : "1"
    }
}
  • Cách 2:
{
    "term" : {
        "id" : "1"
    }
}

Trong trường hợp này, việc sử dụng match query và term query là tương đương.

String query

Để truy vấn một xâu, ta cũng có thể sử dụng match query để tìm kiếm đúng như trong phần trên. Ngoài ra, để truy vấn chỉ một phần nhỏ trong chuỗi, ta có thể dùng một trong các cách sau:

  • Cách 1:
{
    "match" : {
        "message" : {
            "query" : "pre",
            "type" : "phrase_prefix"
        }
    }
}

Query này có thể tìm được các từ có prefix trong query

  • Cách 2:
{
    "wildcard" : { "name" : "ki*y" }
}

Sử dụng cách này có thể query cùng với các kí tự thay thế đặc biệt trong linux như kí tự '*' dùng để thay thế cho một xâu con bất kì, kí tự '?' để thay thế cho một kí tự bất kì, hoặc truy vấn bằng regular expression.

  • Cách 3:
{
    "query_string" : {
        "default_field" : "content",
        "query" : "this AND that OR thus"
    }
}

Hàm query_string cho phép sử dụng các biểu thức logic AND/OR vào trong câu truy vấn. Thích hợp cho những xử lí phức tạp.

Mỗi cách đều có ưu nhược điểm riêng, vậy nên tùy vào yêu cầu mà sử dụng câu truy vấn hiệu quả nhất.

Range query

Với những trường có giá trị số hoặc thời gian như tuổi, ngày tháng năm sinh, đôi khi ta không cần tìm chính xác mà cần tìm kiếm trong một khoảng nào đó. Vì thế, Elastic search cung cấp range query để tìm kiếm các giá trị theo khoảng.

Tìm kiếm theo khoảng:

{
    "range" : {
        "age" : {
            "gte" : 10,
            "lte" : 20
        }
    }
}

Các hàm so sánh:

  • gte - Lớn hơn hoặc bằng
  • lte - Nhỏ hơn hoặc bằng
  • ge - Lớn hơn
  • le - Nhỏ hơn

Ngoài ra có thể dùng hàm from - to để so sánh khoảng (from - to tương đương với gte - lte).

Một câu range query không bắt buộc phải có đầy đủ các hàm.

Tương tự với tìm kiếm theo khoảng thời gian:

{
    "range" : {
        "birthday" : {
            "ge": "01/01/2012",
            "le": "2013"
        }
    }
}

Multi match query

Để truy vấn trên nhiều trường, thay vì phải viết query trên từng trường một, ta chỉ cần viết một query duy nhất trên tất cả các trường, đó chính là multi match query.

{
    "multi_match" : {
        "query":    "this is a test",
        "fields": ["subject", "message"]
    }
}

Tìm kiếm các kí tự đặc biệt

Elastic search thực hiện đánh index theo từng từ trong đó các kí tự đặc biệt được cũng sử dụng để phân chia các từ với nhau. Điều đó đồng nghĩa với việc, trong điều kiện bình thường, Elastic search sẽ không thực hiện việc đánh index cho các kí tự đặc biệt, nói cách khác là ta không thể thực hiện tìm kiếm khi với các kí tự đặc biệt.

Để giải quyết vấn đề này, ta phải sử dụng phương pháp đánh index đặc biệt, đó là đặt ra các analyzer và tokenizer đặc biệt giúp đánh index cho cả những kí tự đặc biệt này.

{
    "settings" : {
        "analysis" : {
            "analyzer" : {
                "my_ngram_analyzer" : {
                    "tokenizer" : "my_ngram_tokenizer"
                }
            },
            "tokenizer" : {
                "my_ngram_tokenizer" : {
                    "type" : "nGram",
                    "token_chars": ["letter", "digit", "whitespace", "punctuation", "symbol"]
                }
            }
        }
    }
}

Trong đó:

  • letter - Các chữ cái như a, b, ï và 京
  • digit - Các chữ số như 3 và 7
  • whitespace - Các kí tự khoảng trắng như space và
  • punctuation - Các dấu câu như ! và "
  • symbol - Các kí hiệu như @, # và &

Ghép các câu truy vấn

Trong các form search phức tạp, query đòi hỏi nhiều tầng logic, tìm kiếm nhiều trường với nhiều điều kiện khác nhau, ta có thể ghép tất cả các câu truy vần vào trong một câu query duy nhất: đó là bool query. Cấu trúc một câu bool query gồm có 3 phần: must, must_not và should. Mỗi phần gồm một dãy các câu query khác. Chức năng mỗi phần:

  • must: Các kết quả PHẢI thỏa mãn các câu query
  • must_not: Các kết quả PHẢI KHÔNG thỏa mãn các câu query
  • should: Các kết quả thỏa mãn MỘT TRONG các câu query

Như các câu query khác, một câu bool query không bắt buộc phải có đủ ba phần trên.

Đặc biệt, trong mỗi phần của bool query có thể chứa một hoặc nhiều bool query khác! Điều này có nghĩa là việc mở rộng các câu truy vấn là vô hạn!

{
    "bool" : {
        "must" : [
            "term" : {"location" : "hanoi"},
            "term" : {"subject" : "math"},
        ],
        "must_not" : [
            "range" : {
                "age" : { "from" : 10, "to" : 20 }
            }
        ],
        "should" : [
            {
                "term" : { "tag" : "wow" }
            },
            {
                "term" : { "tag" : "elasticsearch" }
            }
        ]
    }
}
Bài liên quan

Học SQL cơ bản và nâng cao

[Học SQL cơ bản và nâng cao] SQL (là viết tắt của Structured Query Language – Ngôn ngữ truy vấn mang tính cấu trúc) được sử dụng để thực hiện các hoạt động trên các bản ghi được lưu trữ trong Database (Cơ sở dữ liệu), chẳng hạn như cập nhật các bản ghi, xóa các bản ghi, tạo và sửa đổi ...

Trịnh Tiến Mạnh viết 11:07 ngày 14/08/2018

Học Struts 2 cơ bản và nâng cao

Struts 2 Framework được sử dụng để phát triển ứng dụng web dựa trên MVC. Struts Framework đầu tiên được tạo bởi Craig McClanahan và được bảo trợ bởi Apache Foundation vào tháng 5/2000 và Struts 1.0 được công bố vào tháng 6/2001. Phiên bản hiện tại là Struts 2.3.16.1 được công bố ...

Trịnh Tiến Mạnh viết 10:43 ngày 14/08/2018

Học Java Swing cơ bản và nâng cao

Java Swing là một phần của Java Foundation Classes (JFC) được sử dụng để tạo các ứng dụng Window-Based. Nó được xây dựng ở trên cùng của AWT (Abstract Windowing Toolkit) API và được viết hoàn toàn bằng Java. Không giống AWT, Java Swing cung cấp các thành phần (Component) gọn nhẹ ...

Tạ Quốc Bảo viết 10:40 ngày 14/08/2018

Học Javascript cơ bản và nâng cao, Học lập trình Javascript miễn phí hay nhất

[Học Javascript cơ bản và nâng cao, Học lập trình Javascript miễn phí hay nhất] JavaScript là một ngôn ngữ chương trình thông dịch, nhẹ. Nó được thiết kế để tạo các ứng dụng mạng trung tâm. Nó là ngôn ngữ tích hợp với Java, được lấy tên là JavaScript vì thời đó Java là một hiện tượng, nhưng ...

Trịnh Tiến Mạnh viết 10:37 ngày 14/08/2018

Học Java cơ bản và nâng cao

Java là ngôn ngữ lập trình máy tính có tính chất hướng đối tượng, dựa trên các lớp, thường được sử dụng cho các hệ thống có tính độc lập cao. Nó được sử dụng để hướng tới các lập trình viên viết ứng dụng "write one, run everywhere" (viết một lần, chạy mọi nơi, nghĩa là đoạn code Java ...

Trịnh Tiến Mạnh viết 10:35 ngày 14/08/2018
0