検索システムに OpenSearch を導入するまで #1
概要
個人で開発しているサービスにて検索機能を導入するときに AWS OpenSearch Service とローカルでの開発環境の構築で詰まる所が多かったので備忘録的記事です。
ゴール
- ローカルに OpenSearch の開発環境を作成する
- AWS OpenSearch Service を作成し、データの登録を行う
触れないこと
- OpenSearch の細かなチューニング
- OpenSearch からの検索 ( 後日、気が向いたら書く )
環境
Docker
Version: 20.10.17
OpenSearch
Version: 1.3.0
AWS OpenSearch Service
Version: 1.3.0
ローカル開発環境の構築
お馴染みの Docker で開発環境の構築を行います。
後述のマッピングで利用するための tokenizer, analyzer を利用するため、公式の Docker イメージをそのまま利用するのではなく自前で Dockerfile を用意します。
FROM opensearchproject/opensearch:1.3.0
RUN /usr/share/opensearch/bin/opensearch-plugin install analysis-kuromoji analysis-icu
上記の Dockerfile を利用し docker-compose.yaml を用意します。
version: “3.9”
services:
opensearch:
build:
context: opensearch
environment:
— discovery.type=single-node
ports:
— “9200:9200”
volumes:
— ./opensearch/data:/usr/share/opensearch/data
AWS OpenSearch Service の構築
今回は最低限の環境を構築するため t3.small.search
を利用します。
AWS OpenSearch Service の場合、ローカルで追加でインストールした Plugin は既に組み込まれているため特に意識する必要はありません。
インデックスマッピングの登録
今回は簡単に、 title
と created_at
のみを登録する例を記載しています。 title
には Analyzer として ja_text_analyzer
を利用しています。
created_at
はGo の time.Time
をそのまま利用出来る date_time
を指定しています。
{
"settings": {
"index": {
"analysis": {
"tokenizer": {
"ja_text_tokenizer": {
"type": "kuromoji_tokenizer",
"mode": "search"
}
},
"analyzer": {
"ja_text_analyzer": {
"tokenizer": "ja_text_tokenizer",
"type": "custom",
"char_filter": [
"icu_normalizer"
],
"filter": [
"kuromoji_part_of_speech"
]
}
}
}
}
},
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "ja_text_analyzer"
},
"created_at": {
"type": "date",
"format": "date_time"
}
}
}
}
上記 json を OpenSearch のインデックスとして登録します。
Go などのアプリケーションから行うことも出来ますが、今回は curl
を用いた登録方法を利用します。
ローカルからの接続時に TLS 証明書の設定を行っていない場合は --insecure
オプションをつけて操作します。
AWS OpenSearch Service の場合、 -u
以降の認証情報を必要に応じて変更してください。
curl --insecure -H “Content-Type: application/json” -XPUT <OpenSearch Address>/<Index Name> -u admin:admin -d @schemas/items.json
登録後は以下のコマンドでインデックス情報を確認することが出来ます。
curl -XGET <OpenSearch Address>/<Index Name> -u ‘admin:admin’
Go での利用方法
OpenSearch を Go から利用するため今回は opensearch-project/opensearch-go を利用します。
クライアントの初期化
OpensearchAddr
には OpenSearch のドメイン名を指定します。ローカルの場合 https://localhost:9200
、 AWS OpenSearch Service の場合はインスタンス作成時に発行された ドメインエンドポイント を指定します。 OpensearchUser, OpensearchPassword はローカルの場合は共に admin 、 AWS OpenSearch Service の場合はインスタンス作成時に指定したユーザ、パスワードを指定します。
ローカルの場合は証明書を利用していないため Transport で InsecureSkipVerify: true
を設定します。
opensearchConfig := opensearch.Config{
Addresses: []string{
OpensearchAddr,
},
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
},
Username: OpensearchUser,
Password: OpensearchPassword,
}
opensearchClient, err := opensearch.NewClient(opensearchConfig)
if err != nil {
logger.Error(err.Error())
}
データの登録
osItem := model.ItemOpensearch{
Title: item.Title,
CreatedAt: item.CreatedAt,
}
b, err := json.Marshal(osItem)
if err != nil {
return err
}
r := bytes.NewReader(b)
_, err = opensearchClient.Create("item", item.ID.String(), r) // 第一引数には OpenSearch のインデックス名を指定します。第二引数はドキュメントの ID を指定します。
if err != nil {
return err
}
Discussion