[Elasticsearch PHP] Search APIs

Chắc hẳn thuật ngữ Elasticsearch không còn xa lạ với bất kỳ ai làm nghề lập trình. Hay ngay cả khi bạn mới bước chân vào con đường trờ thành một lập trình viên chuyên nghiệp thì vấn đề tìm kiếm tài lại về Elasticsearch cũng không còn quá khó khăn. Trong bài viết này, tôi sẽ tổng hợp lại một vài kiến thức trong mục Search APIs đối với Elasticsearch trong PHP.

Hầu hết các Search APIs đều là multi-index, multi-type. Ngoại trừ các điểm cuối của Explan API. Sau đây sẽ là một số thuật ngữ cơ bản trong Search APIs

Routing

Khi thực hiện search, nó sẽ được truyền đi tới tất cả các index/indices dưới dạng từng mảnh nhỏ (shards). Những shards dùng để tìm kiếm bên trên có thể được điều khiển bằng các tham số định tuyến (routing). Ví dụ như:

POST /twitter/tweet?routing=kimchy
{
    "user" : "kimchy",
    "postDate" : "2009-11-15T14:12:12",
    "message" : "trying out Elasticsearch"
}

Trong trường hợp này, nếu chúng ta chỉ muốn tìm kiếm cho một người cụ thể , chúng ta có thể chỉ định nó như là một routing, dẫn đến việc tìm kiếm chỉ tìm kiếm những mảnh có liên quan

POST /twitter/tweet/_search?routing=kimchy
{
    "query": {
        "bool" : {
            "must" : {
                "query_string" : {
                    "query" : "some query string here"
                }
            },
            "filter" : {
                "term" : { "user" : "kimchy" }
            }
        }
    }
}

Tham số routing có thể truyền vào nhiều giá trị. Biểu diễn dưới dạng chuỗi, và được ngăng cách nhau bằng dấu phẩy.

Adaptive Replica Selection

Là sự thay thế cho các yêu cầu được gửi đến các bản sao của dữ liệu theo kiểu robin fashion, bạn có thể bật chức năng sao chép thích ứng. Điều này cho phép coordinating node gửi yêu cầu tới các bản sao được coi là tốt nhất dựa trên một số tiêu chí:

  • Thời gian đáp ứng các yêu cầu giữa coordinating node và node containing
  • Thời gian tìm kiếm trên node có chưa dữ liệu
  • Kích thước hàng đợi tìm kiếm trên node có chứa dữ liệu

Nó có thể được kích hoạt bằng cách thay đổi cài đặt dynamic clustering cluster.routing.use_adaptive_replica_selection từ false sang true.

PUT /_cluster/settings
{
    "transient": {
        "cluster.routing.use_adaptive_replica_selection": true
    }
}

Stats Groups

Tìm kiếm có thể kết hợp với một nhóm thống kê. Nó có thể được lấy ra sau này bằng cách sử dụng indices stats API. Ví dụ

POST /_search
{
    "query" : {
        "match_all" : {}
    },
    "stats" : ["group1", "group2"]
}

Multi-Index, Multi-Type

Tất cả API tìm kiếm có thể được áp dụng trên nhiều loại trong một chỉ mục và trên nhiều chỉ số với sự hỗ trợ của cú pháp đa chỉ mục. Ví dụ, chúng ta có thể tìm kiếm tất cả các tài liệu, trên tất cả các loại trong index twitter.

GET /twitter/_search?q=user:kimchy

hoặc tìm kiếm với một type đặc biệt

GET /twitter/tweet,user/_search?q=user:kimchy

Hay tìm kiếm với một thẻ nhất định trên một chỉ số

GET /kimchy,elasticsearch/tweet/_search?q=tag:wow

Hoặc tìm kiếm tất cả trên những index có sẵn bằng cách sử dụng _all

GET /_all/tweet/_search?q=tag:wow

Hoặc đơn giản là search tất cả index và tất cả type

GET /_search?q=tag:wow

URI Search

Một yêu cầu tìm kiếm có thể hoàn toàn thực hiện bằng URI với việc cung cấp các tham số yêu cầu. Không phải tất cả các tùy chọn tìm kiếm đều exposed khi thực hiện chức năng này, nhưng nó có thể hữu ích cho các bài kiểm tra "curl test". Ví dụ

GET twitter/tweet/_search?q=user:kimchy
{
    "timed_out": false,
    "took": 62,
    "_shards":{
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
    },
    "hits":{
        "total" : 1,
        "max_score": 1.3862944,
        "hits" : [
            {
                "_index" : "twitter",
                "_type" : "tweet",
                "_id" : "0",
                "_score": 1.3862944,
                "_source" : {
                    "user" : "kimchy",
                    "date" : "2009-11-15T14:12:12",
                    "message" : "trying out Elasticsearch",
                    "likes": 0
                }
            }
        ]
    }
}

Parameters Các parameters được phép trên URI là:

  • q : Query string (map với query_string query)
  • df : Trường default khi mà không có giá trị trường prefix được định nghĩa trong câu query
  • analyzer: Tên của analyzer được sử dụng khi analyzing câu query
  • analyze_wildcard: Wildcard và prefix query được analyzerd hay không. Giá trị mặc định là false.

Tham khảo thêm tại parameter

Request Body Search Yêu cầu tìm kiếm có thể được thực hiện bởi một DSL tìm kiếm, cái mà chưa query DSL tìm kiếm bên trong body. Ví dụ

GET /twitter/tweet/_search
{
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}

Response trả về như sau:

{
    "took": 1,
    "timed_out": false,
    "_shards":{
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
    },
    "hits":{
        "total" : 1,
        "max_score": 1.3862944,
        "hits" : [
            {
                "_index" : "twitter",
                "_type" : "tweet",
                "_id" : "0",
                "_score": 1.3862944,
                "_source" : {
                    "user" : "kimchy",
                    "message": "trying out Elasticsearch",
                    "date" : "2009-11-15T14:12:12",
                    "likes" : 0
                }
            }
        ]
    }
}

Query

Bạn có thể định nghĩa query DSL bằng cách

GET /_search
{
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}

From / Size

Nếu bạn muốn paginate kết quả tìm kiếm thì cần phải sử dụng From/Size. From là giá trị bắt đầu còn size là maximum amount.

GET /_search
{
    "from" : 0, "size" : 10,
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}

Sort

Sắp xếp kết quả tìm kiếm theo 1 tiêu chí nhất định

PUT /my_index
{
    "mappings": {
        "my_type": {
            "properties": {
                "post_date": { "type": "date" },
                "user": {
                    "type": "keyword"
                },
                "name": {
                    "type": "keyword"
                },
                "age": { "type": "integer" }
            }
        }
    }
}
GET /my_index/my_type/_search
{
    "sort" : [
        { "post_date" : {"order" : "asc"}},
        "user",
        { "name" : "desc" },
        { "age" : "desc" },
        "_score"
    ],
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}