Phần này trình bày cách sử dụng elasticsearch-php là thư viện để PHP kết nối làm việc với Elasticsearch
.
- Cài đặt elasticsearch-php
- Kết nối đến Elasticsearch
- Tạo và xóa một index
- Chỉ mục / xóa / cập nhật Document
- Tìm kiếm với Elasticsearch
- Kỹ thuật Scroll khi tìm kiếm ES
Cài đặt elasticsearch-php
composer require "elasticsearch/elasticsearch"
require 'vendor/autoload.php';
elasticsearch-php
, cũng chú ý là PHP cần có extension ext-curl
(xem thêm
sử dụng curl với php)Cấu hình kết nối PHP tới Elasticsearch
Đối tượng dùng để kết nối tương tác với ES sinh ra từ lớp Elasticsearch/Client
, có có được nó có thể dùng công cụ ClientBuilder
với dữ liệu cầu hình kết nối. Ví dụ:
//Cấu hình kết nối đến ES $hosts = [ [ 'host' => 'localhost', //yourdomain.com 'port' => '9200', 'scheme' => 'http', //https // 'path' => '/elastic', // 'user' => 'username', //nếu ES cần user/pass // 'pass' => 'password!#$?*abc' ], ]; //Tạo đối tượng Client $client = ClientBuilder::create() ->setHosts($hosts) ->build();
Sau khi có $client
thì bắt đầu có thể sử dụng nó để thực hiện các thao tác trên ES như: search
, update
, delete
..., sau đây là một số thao tác sau khi có $client
Tạo / xóa một Index
Ví dụ cần tạo một ES index đặt tên là article
$params = [ 'index' => 'article' ]; //Kiểm tra xem Index đã tồn tại không $indexExist = $client->indices()->exists($params); if (!$indexExist) { try { //Thực hiện tạo Index $response = $client->indices()->create($params); } catch (Exception $e) { //Lỗi tạo Index $res = json_decode($e->getMessage()); echo $res->error->reason; } } else { echo "Index {$params['index']} đã có rồi!"; }
Nếu muốn xóa một Index thì thực hiện như sau:
$params = [ 'index' => 'article' ]; //Kiểm tra xem Index đã tồn tại không $indexExist = $client->indices()->exists($params); if ($indexExist) { $response = $client->indices()->delete($params); echo "Đã xóa"; } else { echo "Index {$params['index']} không có"; }
Chỉ mục, cập nhật, xóa Document
$params = [ 'index' => 'article', //Index lưu Document 'id' => '1', //Nếu thiếu id thì ID tự sinh 'type' => 'article_type', //'timestamp' => time(), // Thiết lập timestamp nếu cần thiết 'body' => [ 'testkey' => 'testvalue'] //Dữ liệu Document ]; $response = $client->index($params);
$params = [ 'body' => [ [ 'index' => ['_index' => 'article', '_type' => 'article_type', ] ], [ 'testkey1' => 'value1', 'testkey2' => 'testkey2'], [ 'index' => ['_index' => 'article', '_type' => 'article_type', ] ], [ 'testkey1' => 'value11', 'testkey2' => 'testkey22'] ] ]; $responses = $client->bulk($params);
$params = [ 'index' => 'article', 'type' => 'article_type', 'id' => '1' ]; $response = $client->get($params);
$params = [ 'index' => 'article', 'type' => 'article_type', 'id' => '1', 'body' => [ 'doc' => [ 'testkey1' => 'valueabc', 'new_field' => 'abc' ] ] ]; $response = $client->update($params);
$params = [ 'index' => 'article', 'type' => 'article_type', 'id' => '1' ]; $response = $client->delete($params);
Tìm kiếm với ES
match query
$params = [ 'index' => 'article', 'type' => 'article_type', 'body' => [ 'query' => [ 'match' => [ 'testkey' => 'testvalue' ] ] ] ]; $results = $client->search($params);
should
, must
...$params = [ 'index' => 'article', 'type' => 'article_type', 'body' => [ 'query' => [ 'bool' => [ 'filter' => [ 'term' => [ 'testkey1' => 'abc' ] ], 'should' => [ ['match' => [ 'testkey1' => 'value1' ]], ['match' => [ 'testkey2' => 'value2' ]] ] ] ] ] ]; $results = $client->search($params);
Kỹ thuật scroll để lấy hết kết quả tìm kiếm
Kỹ thuật scroll giống như sử dụng con trỏ cursor trong truy vấn CSDL SQLServer - một cách để paging dữ liệu.
Ở phần trên,
$client->search($params)
nó trả về tập kết quả - và chỉ lấy được kết quả với số lượng
document mặc định là 10
hoặc chỉ ra trong tham số size
(nhưng lớn nhất là 10000 document).
Lúc này nếu sử dụng scroll bạn sẽ lấy thêm được các kết quả vượt qua size
(page khác).
Cách thực hành như sau:
Truy vấn đầu tiên, thiết lập cho nó thêm một tham số là scroll
gán bằng khoảng thời gian giữ cho
con trỏ tìm kiếm tồn tại, ví dụ 30 giây 30s
, 3 phút là 3m
. Nếu có tham số này thì kết
quả truy vấn đầu tiên sẽ trả về, có kèm một một tham số là id của con trỏ _scroll_id
- nó trỏ đến dòng
kết quả của ngữ cảnh tìm kiếm hiện tại. Từ con trỏ này, yêu cầu lấy các giá trị tiếp theo
$params = [ 'index' => 'article', 'type' => 'article_type', 'scroll' => '1m', // Giữ con trỏ tìm kiếm tồn tại 1m để truy vấn trang tiếp theo 'size' => 10000, // mỗi trang 1000 kết quả 'body' => [ 'query' => [ 'match' => [ 'testkey' => 'testvalue' ] ] ] ]; $response = $client->search($params); // Truy vấn đầu tiên while (isset($response['hits']['hits']) && count($response['hits']['hits']) > 0) { // ** // Viết code xử lý kết quả trả về (đọc) - foreach ($rs['hits']['hits'] as $r) // ** // Khi hoàn thành, lấy scroll_id để lấy kết quả trang tiếp (như 10000 kết quả tiếp theo) $scroll_id = $response['_scroll_id']; // Thực hiện cuộn tới kết quả tiếp theo $response = $client->scroll([ 'scroll_id' => $scroll_id, 'scroll' => '30s' // thiết lập con trỏ tồn tại tiếp 30s ] ); }
Mã nguồn tham khảo: elasticsearch-learning