こんにちは!
ニフティWEBサービス開発グループの伊東です。
本日のテーマは、Elasticsearch-PHP6.0を使ったクエリの作り方についてです。
Elasticsearch-PHPとは
Elasticsearch-PHPとは、外部からElasticsearchを触りたいときに使用されるPHPクライアントです。
他にもJava, JavaScript, Python, Rubyなどありますが、公式ドキュメントがもっとも豊富なのはPHPですね!
ドキュメントの取得
取得は、公式サイトを読めば分かると思います。
1 2 3 4 5 6 7 8 |
$params = [ 'index' => 'my_index', 'type' => 'my_type', 'id' => 'my_id' ]; $response = $client->get($params); print_r($response); |
取得したいドキュメントのindex, type, idをそれぞれ代入して使います。
ドキュメントの検索
検索は、例えばこんな風にかけます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
$params = [ 'index' => 'twitter', 'type' => 'tweet', 'body' => [ 'sort' => ['createDate' => ['order' => 'asc']], 'size' => 1, 'from' => 1, 'query' => [ 'bool' => [ 'must' => [ ['match' => ['content' => 'hello']], ['range' => ['reply' => ['lte' => 3]]] ], 'should' => [ ['term' => ['userName.keyword' => 'Nifta']], ['term' => ['userName.keyword' => 'Nifko']] ], 'minimum_should_match' => 1 ] ] ] ]; $response = $client->search($params); print_r($response); |
この検索条件は、「contentに’hello’が含まれて(match)おり、かつ’reply’が3以下(range)であり、かつuserNameが’Nifta’か’Nifko’と一致(term)しているデータを、createDateの値で昇順に並び替え(sort)、最初の1件をスキップ(from)して、1件(size)を取得する。」を表しています。
‘bool’は複合クエリを表しており、AND検索やOR検索を行う際は基本的にこのboolクエリを使うことになります。
‘must’はAND検索を表しており、指定された条件は必須条件となります。
‘should’はOR検索を表しており、指定されたいずれかの条件が当てはまるものが返却されます。’minimum_should_match’で最低該当件数を指定しています。
‘sort’の’asc’はascendingの略で、昇順という意味ですね。降順にしたい場合は’desc’を入れます。descendingの略ですね。(ソートに関する公式ドキュメント)
‘range’の’lte’は「以下」を意味します。’Less-than or equal to’の略ですね。同じように、「以上」なら’gte’、「未満」なら’lt’、「超過」なら’gt’を入れます。(レンジに関する公式ドキュメント)
‘term’に適用されている’userName.keyword’の’.keyword’は、形態素解析されていないフィールドを指します。よって’.keyword’フィールドには’match’は使えません。(厳密には使えるかもしれませんが、完全一致になるので’term’を使うべきです)
動かしてみます
それでは、実際に動かしてみましょう。
まず、データベースには、こんなデータが入っているとします。(今回はデータの投入方法については話しません)
このデータベースに対して、先ほどのクエリを投げるとどうなるでしょうか。
- 1 -> 条件に該当するので取得される
- 2 -> 条件に該当するので取得される
- 3 -> userNameが’Nifta’でも’Nifko’でもないので取得されない
- 4 -> contentに’hello’が含まれないので取得されない
- 5 -> replyが3を超えているので取得されない
よって、1と2が取得され、createDateフィールドで昇順に並べ替えられ「2, 1」の順番になります。
そして1件スキップされ、1件が取得されるので、結果はid’1’のデータが返ってくるはずです。
それでは、実行してみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
[root@localhost html]# curl localhost/getDoc.php Array ( [took] => 18 [timed_out] => [_shards] => Array ( [total] => 5 [successful] => 5 [skipped] => 0 [failed] => 0 ) [hits] => Array ( [total] => 2 [max_score] => [hits] => Array ( [0] => Array ( [_index] => twitter [_type] => tweet [_id] => 1 [_score] => [_source] => Array ( [userName] => Nifta [createDate] => 2018-01-19T00:00:00 [content] => hello, world! [reply] => 2 ) [sort] => Array ( [0] => 1516320000000 ) ) ) ) ) |
ということで、無事id’1’のデータが返ってきました!
Elasticsearchのクエリは奥が深いので、まだまだ言葉足らずだとは思いますが、まずは基本的な検索をしたい!という方の参考になれば幸いです。