opensearchのクエリ挙動を調査
前提
OpenSeacrhにtextフィールドとkeywordサブフィールドを準備したインデックスを作成する。
"mappings": {
"properties": {
"datetime": {
"type": "date"
},
"title": {
"type": "text"
},
"content": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword"
}
}
}
}
}
気になった事
"type": "text"に対して実行するクエリがあったとする。(=★)
対象のインデックスのの"type": "text"を指定した項目にkeywordサブフィールドを追加する。
この状態で同じ項目の"type": "text"に対する★のクエリは正常に実行できるのか。
keywordsのサブフィールドを追加した事で、デグラないこと(★のクエリが実行できなくなるような事)をかくにんする。
環境
Run OpenSearch in a Docker container
Official OpenSearch images are hosted on Docker Hub and Amazon ECR. If you want to inspect the images you can pull them individually using docker pull, such as in the following examples.
https://opensearch.org/docs/latest/install-and-configure/install-opensearch/docker/
docker pull opensearchproject/opensearch:2
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
opensearchproject/opensearch 2 XXXX 2 weeks ago 1.34GB
インデックスを作成
curl -X PUT "https://localhost:9200/articles" \
-H "Authorization: Basic $(echo -n "ユーザ:パスワード" | base64)" \
-H "Content-Type: application/json" \
--insecure \
-d '{
"mappings": {
"properties": {
"datetime": {
"type": "date"
},
"title": {
"type": "text"
},
"content": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword"
}
}
}
}
}
}'
テストデータを投入
curl -X POST "https://localhost:9200/articles/_bulk" \
-H "Authorization: Basic $(echo -n "ユーザ名:PS" | base64)" \
-H "Content-Type: application/json" \
--insecure \
--data-binary "@data.json"
{"index":{}}
{"datetime":"2024-11-02T10:00:00","title":"朝のミーティング","content":"今日のプロジェクトについて話し合いました。"}
{"index":{}}
{"datetime":"2024-11-02T12:30:00","title":"ランチタイム","content":"新しいカフェでランチを楽しみました。"}
{"index":{}}
{"datetime":"2024-11-02T14:00:00","title":"コーディング","content":"新機能の実装を進めています。"}
{"index":{}}
{"datetime":"2024-11-02T16:00:00","title":"レビュー会議","content":"コードレビューを実施しました。"}
{"index":{}}
{"datetime":"2024-11-02T18:00:00","title":"終業報告","content":"本日の作業をまとめています。"}
クエリを実行
指定した時間の範囲とkeyword
サブフィールドに対して文字数評価のクエリを実行
curl -X GET "https://localhost:9200/articles/_search" \
-H "Authorization: Basic $(echo -n "ユーザ名:PS" | base64)" \
-H "Content-Type: application/json" \
--insecure \
-d '{
"query": {
"bool": {
"must": [
{
"range": {
"datetime": {
"gte": "2024-11-02T13:00:00",
"lt": "2024-11-03T00:00:00"
}
}
}
],
"filter": {
"script": {
"script": {
"source": "doc['"'"'content.keyword'"'"'].value.length() >= 10 && doc['"'"'content.keyword'"'"'].value.length() <= 20",
"lang": "painless"
}
}
}
}
}
}'
想定通り3件取得できたことを確認
{"took":3,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":3,"relation":"eq"},"max_score":1.0,"hits":[{"_index":"articles","_id":"uGNR_ZIBqCfv13uBDf2y","_score":1.0,"_source":{"datetime":"2024-11-02T14:00:00","title":"コーディング","content":"新機能の実装を進めています。"}},{"_index":"articles","_id":"uWNR_ZIBqCfv13uBDf2y","_score":1.0,"_source":{"datetime":"2024-11-02T16:00:00","title":"レビュー会議","content":"コードレビューを実施しました。"}},{"_index":"articles","_id":"umNR_ZIBqCfv13uBDf2y","_score":1.0,"_source":{"datetime":"2024-11-02T18:00:00","title":"終業報告","content":" 本日の作業をまとめています。"}}]}}
クエリを実行
"type": "text"
のcontentフィールドに対して文字数評価のクエリを実行
curl -X GET "https://localhost:9200/articles/_search" \
-H "Authorization: Basic $(echo -n "ユーザ名:PS" | base64)" \
-H "Content-Type: application/json" \
--insecure \
-d @query.json
コマンドにべた書きで日本語記載しcurlで叩くとUTF-8 エンコーディングに関するエラーが発生したため、 JSON データをファイルに検索対象の日本語文字列を保存しcurl でコールした際に読み込む
{
"query": {
"match": {
"content": "プロジェクト"
}
}
}
想定通りデータが1件とれていることを確認
{"took":13,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":1,"relation":"eq"},"max_score":1.2767762,"hits":[{"_index":"articles","_id":"tmNR_ZIBqCfv13uBDf2x","_score":1.2767762,"_source":{"datetime":"2024-11-02T10:00:00","title":"朝のミーティング","content":"今日の プロジェクトについて話し合いました。"}}]}}
下記のようにkeyword
サブフィールドの追加した状態で
- keywordサブフィールドに対するクエリ
- keywordサブフィールドと同じconetntの
"type": "text"
のフィールドに対するクエリ
どちらも正常にクエリは実行できた。
"mappings": {
"properties": {
"datetime": {
"type": "date"
},
"title": {
"type": "text"
},
"content": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword"
}
}
}
}
}
片づけは下記を参考に実施