2021年11月に中途入社した砂原です。バイトルやはたらこねっとなどのHR系サービスの開発を担当している部署に所属しており、社内の技術的な課題や困りごとを調査・検証するようなお仕事をしています。
弊社では現在PostgreSQLを検索基盤として利用しているのですが、今後サイト内検索の利便性を高めていくためにPostgreSQLに変わるものはないかと調査・検証しています。
その中でも今回はOpenSearchを使ってみた系の話を書こうと思います。
OpenSearchについて
OpenSearchの詳しい解説はAWS様のドキュメントにも詳しく書いてあるので割愛します。
一般的にRDBはフリーワード検索や各種集計があまり得意ではないのですが、OpenSearchはその辺りの検索速度や利便性がかなり向上します。
また、Amazon OpenSearch Serviceを使えばかなり容易に検索基盤が構築できるので、もしRDBで検索機能を実現しているが「サイト内検索が遅い」「集計が遅い/もっといい感じの集計をしたい」などあれば、一度試してみる価値があると思います!
ということで、本記事はOpenSearchに触れる第一歩として、Dockerを用いて手元でOpenSearchを動かす手順を取り上げます。
バージョンは執筆時点(2022/6末)で最新が2.0.1なのですが、本記事では2.0.0を取り扱っています。
Dockerを使ってOpenSearchを立ち上げる
手元でサクッと動かす分には1ノードでも良いかと思うので、公式ドキュメントから少し変更しています。こちらはクラスメソッド様の記事を参考にさせていただきました。ありがとうございます!
version: '3' services: opensearch: build: context: . dockerfile: Dockerfile container_name: opensearch environment: - cluster.name=docker-cluster - node.name=opensearch-node - cluster.initial_master_nodes=opensearch-node - bootstrap.memory_lock=true - http.host=0.0.0.0 - transport.host=127.0.0.1 - "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m" ulimits: memlock: soft: -1 hard: -1 volumes: - $PWD/.data/opensearch:/usr/share/opensearch/data ports: - 9200:9200 networks: - opensearch-net opensearch-dashboards: image: opensearchproject/opensearch-dashboards:2.0.0 container_name: opensearch-dashboards environment: OPENSEARCH_HOSTS: "https://opensearch:9200" ports: - 5601:5601 networks: - opensearch-net volumes: opensearch-data: networks: opensearch-net:
Dockerfile内で日本語検索に必要なpluginをインストールします。/tmpに一度ダウンロードしているのですが、直接インストールしてもいいかと思います。
FROM opensearchproject/opensearch:2.0.0 # Download Plugin Files RUN curl -L -k -O https://artifacts.opensearch.org/releases/plugins/analysis-kuromoji/2.0.0/analysis-kuromoji-2.0.0.zip --output-DIR /tmp RUN curl -L -k -O https://artifacts.opensearch.org/releases/plugins/analysis-icu/2.0.0/analysis-icu-2.0.0.zip --output-dir /tmp # Install Plugin RUN /usr/share/opensearch/bin/opensearch-plugin install file:///tmp/analysis-kuromoji-2.0.0.zip RUN /usr/share/opensearch/bin/opensearch-plugin install file:///tmp/analysis-icu-2.0.0.zip
docker compose -d up
を実行します。
これで準備は完了です!
OpenSearch環境の確認
Dashboard
http://localhost:5601/ にアクセスできればOKです。
なお、初期USER/PASSは admin/admin
です。
OpenSearch
https://localhost:9200/ にアクセスし、以下のようなOpenSearchの情報が表示されればOKです。
こちらも初期USER/PASSは admin/admin
です。
{ "name" : "opensearch-node", "cluster_name" : "docker-cluster", "cluster_uuid" : "2fGiy_Q2QsqIRIrfv6Luiw", "version" : { "distribution" : "opensearch", "number" : "2.0.0", "build_type" : "tar", "build_hash" : "bae3b4e4178c20ac24fece8e82099abe3b2630d0", "build_date" : "2022-05-19T00:26:04.115016552Z", "build_snapshot" : false, "lucene_version" : "9.1.0", "minimum_wire_compatibility_version" : "7.10.0", "minimum_index_compatibility_version" : "7.0.0" }, "tagline" : "The OpenSearch Project: https://opensearch.org/" }
次はPHPでOpenSearchを操作してみましょう。
OpenSearch-phpの利用方法
1.composerをインストールする
2.composerにopensearch-phpを追加する
composer require opensearch-project/opensearch-php
3.サンプルスクリプトを用意しました。こちらを実行して動けばOKです。
サンプルスクリプトの処理は以下の通りです。
・pr
とname
いうフィールドをもつtest-index
という名前のインデックスを作成(prはkuromojiを利用するよう設定)
・pr
フィールドに対して京都
というワードで全文検索
・検索結果を表示(東京都はHITせず、京都だけがHITする)
<?php require __DIR__ . '/vendor/autoload.php'; // 環境によって適宜変更してください $opensearchHost = [ 'host' => 'localhost', 'scheme' => 'https', 'port' => '9200' ]; $user = 'admin'; $pass = 'admin'; $indexName = 'test-index'; $client = (new \OpenSearch\ClientBuilder()) ->setHosts([$opensearchHost]) ->setBasicAuthentication($user, $pass) ->setSSLVerification(false) ->build(); // index作成 $indexParams['index'] = $indexName; $exists = $client->indices()->exists($indexParams); if (!$exists) { $client->indices()->create([ 'index' => $indexName, 'body' => [ 'settings' => [ 'index' => [ 'analysis' => [ 'analyzer' => [ 'kuromoji' => [ 'type' => 'custom', 'tokenizer' => 'kuromoji_tokenizer' ] ] ] ] ], 'mappings' => [ 'properties' => [ 'pr' => [ 'type' => 'text', 'analyzer' => 'kuromoji' ], 'name' => [ 'type' => 'text' ] ] ] ] ]); } // データ作成 $client->create([ 'index' => $indexName, 'id' => 1, 'body' => [ 'name' => '田中一郎', 'pr' => '京都に10年住んでいます。' ] ]); $client->create([ 'index' => $indexName, 'id' => 2, 'body' => [ 'name' => '山田花子', 'pr' => '東京都出身です。' ] ]); // データ検索 $result =( $client->search([ 'index' => $indexName, 'body' => [ '_source' => ['name','pr'], 'query' => [ 'match' => [ 'pr' => '京都' ] ] ] ]) ); var_dump($result)
※環境によってはデータ作成後にsleepを数秒入れないと正しく結果が取得できないかもしれません。
以上がDockerを用いて手元でOpenSearchを動かす手順となります。
最後に
OpenSearchはElasticsearch7.10.2から派生したという経緯があるため、もし実装にあたり困ったことが発生した場合はElasticsearch-PHPのドキュメントも参考にすると答えが見つかるかもしれません。
検証時にOpenSearch×PHPのサンプルがなかなか見つからず苦労したので、記事にしてみました。お役に立てると嬉しいです。