OpenSearch アナライザーをカスタマイズする

OpenSearch で登録、検索する際、アナライザーがテキストを解析しています。
アナライザーの設定次第で柔軟な検索が可能になります。

目次

アナライザーによるテキスト解析

まず、アナライザーによってテキストがどんな感じで解析されているのかを確認しましょう。
Analyze API を使って確認できます。
※ テキストは ChatGPT さん作。

デフォルトでは、standard というアラナイザーが設定されるため、standard を指定します。

GET /_analyze
{
  "analyzer": "standard",
  "text": [
    "Cybersecurity and privacy protection have become critical issues."
  ]
}
{
  "tokens": [
    {
      "token": "cybersecurity",
      "start_offset": 0,
      "end_offset": 13,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "and",
      "start_offset": 14,
      "end_offset": 17,
      "type": "<ALPHANUM>",
      "position": 1
    },
    {
      "token": "privacy",
      "start_offset": 18,
      "end_offset": 25,
      "type": "<ALPHANUM>",
      "position": 2
    },
    {
      "token": "protection",
      "start_offset": 26,
      "end_offset": 36,
      "type": "<ALPHANUM>",
      "position": 3
    },
    {
      "token": "have",
      "start_offset": 37,
      "end_offset": 41,
      "type": "<ALPHANUM>",
      "position": 4
    },
    {
      "token": "become",
      "start_offset": 42,
      "end_offset": 48,
      "type": "<ALPHANUM>",
      "position": 5
    },
    {
      "token": "critical",
      "start_offset": 49,
      "end_offset": 57,
      "type": "<ALPHANUM>",
      "position": 6
    },
    {
      "token": "issues",
      "start_offset": 58,
      "end_offset": 64,
      "type": "<ALPHANUM>",
      "position": 7
    }
  ]
}

文章が単語ごとに分割されました。
次に、先ほどのテキストを日本語にしたもので試してみます。

GET /_analyze
{
  "analyzer": "standard",
  "text": [
    "サイバーセキュリティとプライバシー保護は、重要な問題となっています。"
  ]
}

結果

{
  "tokens": [
    {
      "token": "サイバーセキュリティ",
      "start_offset": 0,
      "end_offset": 10,
      "type": "<KATAKANA>",
      "position": 0
    },
    {
      "token": "",
      "start_offset": 10,
      "end_offset": 11,
      "type": "<HIRAGANA>",
      "position": 1
    },
    {
      "token": "プライバシー",
      "start_offset": 11,
      "end_offset": 17,
      "type": "<KATAKANA>",
      "position": 2
    },
    {
      "token": "",
      "start_offset": 17,
      "end_offset": 18,
      "type": "<IDEOGRAPHIC>",
      "position": 3
    },
    {
      "token": "",
      "start_offset": 18,
      "end_offset": 19,
      "type": "<IDEOGRAPHIC>",
      "position": 4
    },
    {
      "token": "",
      "start_offset": 19,
      "end_offset": 20,
      "type": "<HIRAGANA>",
      "position": 5
    },
    {
      "token": "",
      "start_offset": 21,
      "end_offset": 22,
      "type": "<IDEOGRAPHIC>",
      "position": 6
    },
    {
      "token": "",
      "start_offset": 22,
      "end_offset": 23,
      "type": "<IDEOGRAPHIC>",
      "position": 7
    },
    {
      "token": "",
      "start_offset": 23,
      "end_offset": 24,
      "type": "<HIRAGANA>",
      "position": 8
    },
    {
      "token": "",
      "start_offset": 24,
      "end_offset": 25,
      "type": "<IDEOGRAPHIC>",
      "position": 9
    },
    {
      "token": "",
      "start_offset": 25,
      "end_offset": 26,
      "type": "<IDEOGRAPHIC>",
      "position": 10
    },
    {
      "token": "",
      "start_offset": 26,
      "end_offset": 27,
      "type": "<HIRAGANA>",
      "position": 11
    },
    {
      "token": "",
      "start_offset": 27,
      "end_offset": 28,
      "type": "<HIRAGANA>",
      "position": 12
    },
    {
      "token": "",
      "start_offset": 28,
      "end_offset": 29,
      "type": "<HIRAGANA>",
      "position": 13
    },
    {
      "token": "",
      "start_offset": 29,
      "end_offset": 30,
      "type": "<HIRAGANA>",
      "position": 14
    },
    {
      "token": "",
      "start_offset": 30,
      "end_offset": 31,
      "type": "<HIRAGANA>",
      "position": 15
    },
    {
      "token": "",
      "start_offset": 31,
      "end_offset": 32,
      "type": "<HIRAGANA>",
      "position": 16
    },
    {
      "token": "",
      "start_offset": 32,
      "end_offset": 33,
      "type": "<HIRAGANA>",
      "position": 17
    }
  ]
}

入力したテキストが複数のトークンに分割され、テキスト内での位置や、種類などが表示されています。

カタカナ → 分割されず1トーク
ひらがな、漢字 → 1文字1トーク

のようになりました。

トークン単位でインデックス登録されるため、「プライバシー」は検索できますが、「セキュリティ」は検索できません。
日本語は、英語のように単語がスペースで区切られないため解析の難易度が高いです。

日本語向けアナライザー

次に日本語向けのアナライザーを試してみます。
日本語向けのアナライザーは Dockerfile でプラグインとして導入した kuromoji, icu が有名らしいです。
kuromoji を使ってみましょう。

GET /_analyze
{
  "analyzer": "kuromoji",
  "text": [
    "サイバーセキュリティとプライバシー保護は、重要な問題となっています。"
  ]
}

結果

{
  "tokens": [
    {
      "token": "サイ",
      "start_offset": 0,
      "end_offset": 2,
      "type": "word",
      "position": 0
    },
    {
      "token": "バー",
      "start_offset": 2,
      "end_offset": 4,
      "type": "word",
      "position": 1
    },
    {
      "token": "セキュリティ",
      "start_offset": 4,
      "end_offset": 10,
      "type": "word",
      "position": 2
    },
    {
      "token": "プライバシ",
      "start_offset": 11,
      "end_offset": 17,
      "type": "word",
      "position": 4
    },
    {
      "token": "保護",
      "start_offset": 17,
      "end_offset": 19,
      "type": "word",
      "position": 5
    },
    {
      "token": "重要",
      "start_offset": 21,
      "end_offset": 23,
      "type": "word",
      "position": 7
    },
    {
      "token": "問題",
      "start_offset": 24,
      "end_offset": 26,
      "type": "word",
      "position": 9
    }
  ]
}

kuromoji による解析では、カタカナが分割されていたり、漢字が熟語で分割されていたり、日本語として意味のある形に解析(形態素解析)できています。 今回は「セキュリティ」が1トークンになっているため、「セキュリティ」で検索できます。
アナライザーによって検索具合が変わることが分かります。

アナライザーのカスタマイズ

アナライザーはカスタマイズが可能です。

アナライザーの構成要素

  • charfilter:文字単位の処理を行うもの
  • tokenizer:テキストをトークンに分割するもの
  • filter:分割されたトークンに処理を行うもの

先ほど使った kuromoji や icu は、charfilter, tokenizer, filter 単位で機能が提供されています。

ICU の機能

https://www.elastic.co/guide/en/elasticsearch/plugins/current/analysis-icu.html

  • ICU Normalization Character Filter
    • 文字の正規化
    • 全角を半角に変換
    • ㌢ → センチ なども変換可能
  • ICU Tokenizer
  • ICU normalization token filter
    • 文字の正規化
    • ICU Normalization Character Filter の token filter バージョン
  • ICU folding token filter
    • 長音の統一
    • ふう → フー など
  • ICU collation keyword field
    • 言語固有の語順にソート
  • ICU transform token filter
    • 音訳

この中だと、ICU Normalization Character Filter がよく使われている印象です。(主観です。)

kuromoji の機能

https://www.elastic.co/guide/en/elasticsearch/plugins/current/analysis-kuromoji.html

  • kuromoji_iteration_mark character filter
    • 踊り文字の正規化
  • kuromoji_tokenizer
    • トークン化
    • normal, search, extended の3モードがある
  • kuromoji_baseform token filter
    • 原形化
    • 飲み → 飲む など
  • kuromoji_part_of_speech token filter
    • 検索に有用ではない助詞などの品詞の除去
  • kuromoji_readingform token filter
    • 漢字に読み仮名を付与する
    • かなとローマ字から選べる
  • kuromoji_stemmer token filter
    • 長音の除去
    • サーバー → サーバ
  • ja_stop token filter
  • kuromoji_number token filter
    • 漢数字の半角数字化
    • 百 → 100 など

N-gram tokenizer

これまでとは一転して文の意味などは考えず、文字数ごとにトークン化します。

GET /_analyze
{
  "tokenizer": {
    "type": "ngram",
    "min_gram": 2,
    "max_gram": 2
  },
  "text": [
    "サイバーセキュリティとプライバシー保護は、重要な問題となっています。"
  ]
}
{
  "tokens": [
    {
      "token": "サイ",
      "start_offset": 0,
      "end_offset": 2,
      "type": "word",
      "position": 0
    },
    {
      "token": "イバ",
      "start_offset": 1,
      "end_offset": 3,
      "type": "word",
      "position": 1
    },
    {
      "token": "バー",
      "start_offset": 2,
      "end_offset": 4,
      "type": "word",
      "position": 2
    },
    {
      "token": "ーセ",
      "start_offset": 3,
      "end_offset": 5,
      "type": "word",
      "position": 3
    },
    {
      "token": "セキ",
      "start_offset": 4,
      "end_offset": 6,
      "type": "word",
      "position": 4
    },
    {
      "token": "キュ",
      "start_offset": 5,
      "end_offset": 7,
      "type": "word",
      "position": 5
    },
    {
      "token": "ュリ",
      "start_offset": 6,
      "end_offset": 8,
      "type": "word",
      "position": 6
    },
    {
      "token": "リテ",
      "start_offset": 7,
      "end_offset": 9,
      "type": "word",
      "position": 7
    },
    {
      "token": "ティ",
      "start_offset": 8,
      "end_offset": 10,
      "type": "word",
      "position": 8
    },
    {
      "token": "ィと",
      "start_offset": 9,
      "end_offset": 11,
      "type": "word",
      "position": 9
    },
    {
      "token": "とプ",
      "start_offset": 10,
      "end_offset": 12,
      "type": "word",
      "position": 10
    },
    {
      "token": "プラ",
      "start_offset": 11,
      "end_offset": 13,
      "type": "word",
      "position": 11
    },
    {
      "token": "ライ",
      "start_offset": 12,
      "end_offset": 14,
      "type": "word",
      "position": 12
    },
    {
      "token": "イバ",
      "start_offset": 13,
      "end_offset": 15,
      "type": "word",
      "position": 13
    },
    {
      "token": "バシ",
      "start_offset": 14,
      "end_offset": 16,
      "type": "word",
      "position": 14
    },
    {
      "token": "シー",
      "start_offset": 15,
      "end_offset": 17,
      "type": "word",
      "position": 15
    },
    {
      "token": "ー保",
      "start_offset": 16,
      "end_offset": 18,
      "type": "word",
      "position": 16
    },
    {
      "token": "保護",
      "start_offset": 17,
      "end_offset": 19,
      "type": "word",
      "position": 17
    },
    {
      "token": "護は",
      "start_offset": 18,
      "end_offset": 20,
      "type": "word",
      "position": 18
    },
    {
      "token": "は、",
      "start_offset": 19,
      "end_offset": 21,
      "type": "word",
      "position": 19
    },
    {
      "token": "、重",
      "start_offset": 20,
      "end_offset": 22,
      "type": "word",
      "position": 20
    },
    {
      "token": "重要",
      "start_offset": 21,
      "end_offset": 23,
      "type": "word",
      "position": 21
    },
    {
      "token": "要な",
      "start_offset": 22,
      "end_offset": 24,
      "type": "word",
      "position": 22
    },
    {
      "token": "な問",
      "start_offset": 23,
      "end_offset": 25,
      "type": "word",
      "position": 23
    },
    {
      "token": "問題",
      "start_offset": 24,
      "end_offset": 26,
      "type": "word",
      "position": 24
    },
    {
      "token": "題と",
      "start_offset": 25,
      "end_offset": 27,
      "type": "word",
      "position": 25
    },
    {
      "token": "とな",
      "start_offset": 26,
      "end_offset": 28,
      "type": "word",
      "position": 26
    },
    {
      "token": "なっ",
      "start_offset": 27,
      "end_offset": 29,
      "type": "word",
      "position": 27
    },
    {
      "token": "って",
      "start_offset": 28,
      "end_offset": 30,
      "type": "word",
      "position": 28
    },
    {
      "token": "てい",
      "start_offset": 29,
      "end_offset": 31,
      "type": "word",
      "position": 29
    },
    {
      "token": "いま",
      "start_offset": 30,
      "end_offset": 32,
      "type": "word",
      "position": 30
    },
    {
      "token": "ます",
      "start_offset": 31,
      "end_offset": 33,
      "type": "word",
      "position": 31
    },
    {
      "token": "す。",
      "start_offset": 32,
      "end_offset": 34,
      "type": "word",
      "position": 32
    }
  ]
}

結果を見ると、文章が2文字ずつのトークンになっていることがわかります。

N-gram を使うことで、形態素解析によって分割された単語より短い文字列で検索されても対応できます。
例えば、「サイ」で検索して「サイバーセキュリティ」を含むドキュメントをヒットさせるみたいな感じです。

カスタムしたアナライザーを利用した検索

kuromoji ベース

漢字を読み仮名で検索できるようにしてみます。

インデックス作成(Mapping 定義)

PUT /documents
{
  "settings": {
    "analysis": {
      "char_filter": {
        "normalize": {
          "type": "icu_normalizer",
          "name": "nfkc",
          "mode": "compose"
        }
      },
      "analyzer": {
        "kuromoji_analyzer": {
          "type": "custom",
          "char_filter": [
            "normalize"
          ],
          "tokenizer": "kuromoji_tokenizer",
          "filter": [
            "kuromoji_readingform"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "content": {
        "type": "text",
        "analyzer": "kuromoji_analyzer",
        "search_analyzer": "kuromoji_analyzer",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "created_by": {
        "type": "text",
        "analyzer": "kuromoji_analyzer",
        "search_analyzer": "kuromoji_analyzer",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "title": {
        "type": "text",
        "analyzer": "kuromoji_analyzer",
        "search_analyzer": "kuromoji_analyzer",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      }
    }
  }
}

ドキュメント登録

POST /documents/_bulk
{"index":{"_index":"documents","_id":"1"}}
{"title":"サイバーセキュリティとプライバシー保護","content":"サイバーセキュリティとプライバシー保護は、現代社会においてますます重要な問題となっています。インターネットの普及により、個人や企業のデータがオンライン上で共有される機会が増え、それに伴う脅威も増加しています。個人情報の漏洩や機密データの盗難は、経済的な損失だけでなく、個人や組織の信頼をも損なう可能性があります。そのため、適切なセキュリティ対策とプライバシー保護が求められています。","created_by":"user-1"}
{"index":{"_index":"documents","_id":"2"}}
{"title":"テクノロジーと教育の融合","content":"現代の教育では、テクノロジーがますます重要な役割を果たしています。インタラクティブな学習アプリケーションやオンライン教材を活用することで、生徒たちはより効果的に学び、自分のペースで進歩することができます。また、教師はデータ分析ツールを使用して生徒の進歩を追跡し、個々のニーズに合った指導を提供することができます。テクノロジーと教育の融合は、教育の質とアクセス性を向上させるための重要な手段です。","created_by":"user-1"}
{"index":{"_index":"documents","_id":"3"}}
{"title":"リモートワークの未来","content":"リモートワークは、近年急速に普及しています。技術の進歩により、従業員は自宅やカフェからでも仕事を行うことが可能になりました。これにより、通勤時間の削減や地理的な制約の克服が可能になり、生産性の向上が期待されています。しかし、リモートワークにはコミュニケーションの課題や労働時間の管理などの課題もあります。これらの課題を克服するために、企業は柔軟な労働政策や適切なテクノロジーの導入を検討する必要があります。","created_by":"user-1"}
{"index":{"_index":"documents","_id":"4"}}
{"title":"グリーンテクノロジーと持続可能性","content":"グリーンテクノロジーは、環境への負荷を最小限に抑えるための技術革新を指します。再生可能エネルギー、エネルギー効率の向上、廃棄物のリサイクルなど、様々な分野でグリーンテクノロジーの進化が進んでいます。これにより、地球温暖化や環境汚染といった課題に対処するための解決策が提供されています。持続可能な未来を実現するためには、グリーンテクノロジーの積極的な採用が不可欠です。","created_by":"user-2"}
{"index":{"_index":"documents","_id":"5"}}
{"title":"人工知能と倫理","content":"人工知能(AI)の進化は、私たちの生活や社会に大きな影響を与えています。自動運転車や自動化された顧客サービスなど、AIの応用範囲はますます広がっています。しかし、AIの使用には倫理的な問題も伴います。例えば、個人のプライバシーの侵害や差別的な意思決定が起こる可能性があります。このようなリスクを最小限に抑えるために、AIの開発と使用には倫理的なガイドラインが必要です。","created_by":"user-2"}

検索

GET /documents/_search
{
  "query": {
    "multi_match": {
      "query": "かのう",
      "fields": [
        "content"
      ]
    }
  },
  "_source": [
    "title",
    "created_by"
  ],
  "highlight": {
    "fields": {
      "content": {}
    }
  }
}

結果

{
  "took": 14,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 4,
      "relation": "eq"
    },
    "max_score": 0.40681702,
    "hits": [
      {
        "_index": "documents",
        "_id": "4",
        "_score": 0.40681702,
        "_source": {
          "title": "グリーンテクノロジーと持続可能性",
          "created_by": "user-2"
        },
        "highlight": {
          "content": [
            "再生<em>可能</em>エネルギー、エネルギー効率の向上、廃棄物のリサイクルなど、様々な分野でグリーンテクノロジーの進化が進んでいます。",
            "持続<em>可能</em>な未来を実現するためには、グリーンテクノロジーの積極的な採用が不可欠です。"
          ]
        }
      },
      {
        "_index": "documents",
        "_id": "3",
        "_score": 0.38839975,
        "_source": {
          "title": "リモートワークの未来",
          "created_by": "user-1"
        },
        "highlight": {
          "content": [
            "技術の進歩により、従業員は自宅やカフェからでも仕事を行うことが<em>可能</em>になりました。これにより、通勤時間の削減や地理的な制約の克服が<em>可能</em>になり、生産性の向上が期待されています。"
          ]
        }
      },
      {
        "_index": "documents",
        "_id": "1",
        "_score": 0.2997433,
        "_source": {
          "title": "サイバーセキュリティとプライバシー保護",
          "created_by": "user-1"
        },
        "highlight": {
          "content": [
            "個人情報の漏洩や機密データの盗難は、経済的な損失だけでなく、個人や組織の信頼をも損なう<em>可能</em>性があります。そのため、適切なセキュリティ対策とプライバシー保護が求められています。"
          ]
        }
      },
      {
        "_index": "documents",
        "_id": "5",
        "_score": 0.28962442,
        "_source": {
          "title": "人工知能と倫理",
          "created_by": "user-2"
        },
        "highlight": {
          "content": [
            "例えば、個人のプライバシーの侵害や差別的な意思決定が起こる<em>可能</em>性があります。このようなリスクを最小限に抑えるために、AIの開発と使用には倫理的なガイドラインが必要です。"
          ]
        }
      }
    ]
  }
}

Ngram

一度先ほどのインデックスを削除します。

DELETE /documents

インデックス作成

PUT /documents
{
  "settings": {
    "analysis": {
      "tokenizer": {
        "ngram_tokenizer": {
          "type": "ngram",
          "min_gram": 1,
          "max_gram": 1
        }
      },
      "analyzer": {
        "custom_analyzer": {
          "type": "custom",
          "tokenizer": "ngram_tokenizer"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "content": {
        "type": "text",
        "analyzer": "custom_analyzer",
        "search_analyzer": "custom_analyzer",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "created_by": {
        "type": "text",
        "analyzer": "custom_analyzer",
        "search_analyzer": "custom_analyzer",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "title": {
        "type": "text",
        "analyzer": "custom_analyzer",
        "search_analyzer": "custom_analyzer",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      }
    }
  }
}

ドキュメントは先ほどと同じものを使い、検索します。

GET /documents/_search
{
  "query": {
    "multi_match": {
      "query": "テクノ",
      "fields": [
        "content"
      ]
    }
  },
  "_source": [
    "title",
    "created_by"
  ],
  "highlight": {
    "fields": {
      "content": {}
    }
  }
}

結果

{
  "took": 12,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 5,
      "relation": "eq"
    },
    "max_score": 1.8317354,
    "hits": [
      {
        "_index": "documents",
        "_id": "4",
        "_score": 1.8317354,
        "_source": {
          "title": "グリーンテクノロジーと持続可能性",
          "created_by": "user-2"
        },
        "highlight": {
          "content": [
            "グリーン<em>テ</em><em>ク</em><em>ノ</em>ロジーは、環境への負荷を最小限に抑えるための技術革新を指します。再生可能エネルギー、エネルギー効率の向上、廃棄物のリサイ<em>ク</em>ルなど、様々な分野でグリーン<em>テ</em><em>ク</em><em>ノ</em>ロジーの進化が進んでいます。",
            "持続可能な未来を実現するためには、グリーン<em>テ</em><em>ク</em><em>ノ</em>ロジーの積極的な採用が不可欠です。"
          ]
        }
      },
      {
        "_index": "documents",
        "_id": "2",
        "_score": 1.6956408,
        "_source": {
          "title": "テクノロジーと教育の融合",
          "created_by": "user-1"
        },
        "highlight": {
          "content": [
            "現代の教育では、<em>テ</em><em>ク</em><em>ノ</em>ロジーがますます重要な役割を果たしています。",
            "インタラ<em>ク</em><em>テ</em>ィブな学習アプリケーションやオンライン教材を活用することで、生徒たちはより効果的に学び、自分のペースで進歩することができます。",
            "<em>テ</em><em>ク</em><em>ノ</em>ロジーと教育の融合は、教育の質とア<em>ク</em>セス性を向上させるための重要な手段です。"
          ]
        }
      },
      {
        "_index": "documents",
        "_id": "3",
        "_score": 1.2599776,
        "_source": {
          "title": "リモートワークの未来",
          "created_by": "user-1"
        },
        "highlight": {
          "content": [
            "リモートワー<em>ク</em>は、近年急速に普及しています。技術の進歩により、従業員は自宅やカフェからでも仕事を行うことが可能になりました。",
            "しかし、リモートワー<em>ク</em>にはコミュニケーションの課題や労働時間の管理などの課題もあります。これらの課題を克服するために、企業は柔軟な労働政策や適切な<em>テ</em><em>ク</em><em>ノ</em>ロジーの導入を検討する必要があります。"
          ]
        }
      },
      {
        "_index": "documents",
        "_id": "1",
        "_score": 0.40002558,
        "_source": {
          "title": "サイバーセキュリティとプライバシー保護",
          "created_by": "user-1"
        },
        "highlight": {
          "content": [
            "サイバーセキュリ<em>テ</em>ィとプライバシー保護は、現代社会においてますます重要な問題となっています。",
            "そのため、適切なセキュリ<em>テ</em>ィ対策とプライバシー保護が求められています。"
          ]
        }
      },
      {
        "_index": "documents",
        "_id": "5",
        "_score": 0.2924273,
        "_source": {
          "title": "人工知能と倫理",
          "created_by": "user-2"
        },
        "highlight": {
          "content": [
            "このようなリス<em>ク</em>を最小限に抑えるために、AIの開発と使用には倫理的なガイドラインが必要です。"
          ]
        }
      }
    ]
  }
}

「テクノ」を含むドキュメントがヒットするようになりました。
ただ、「テ」、「ク」のみ存在するドキュメントもヒットしています。

これを弾きたい場合は、クエリをちょっと変えることで対応できます。

GET /documents/_search
{
  "query": {
    "match_phrase": { // クエリのテキストを1フレーズとして扱います。
      "content": {
        "query": "テクノ"
      }
    }
  },
  "_source": [
    "title",
    "created_by"
  ],
  "highlight": {
    "fields": {
      "content": {}
    }
  }
}

結果

{
  "took": 56,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 3,
      "relation": "eq"
    },
    "max_score": 1.7986114,
    "hits": [
      {
        "_index": "documents",
        "_id": "4",
        "_score": 1.7986114,
        "_source": {
          "title": "グリーンテクノロジーと持続可能性",
          "created_by": "user-2"
        },
        "highlight": {
          "content": [
            "グリーン<em>テ</em><em>ク</em><em>ノ</em>ロジーは、環境への負荷を最小限に抑えるための技術革新を指します。再生可能エネルギー、エネルギー効率の向上、廃棄物のリサイクルなど、様々な分野でグリーン<em>テ</em><em>ク</em><em>ノ</em>ロジーの進化が進んでいます。",
            "持続可能な未来を実現するためには、グリーン<em>テ</em><em>ク</em><em>ノ</em>ロジーの積極的な採用が不可欠です。"
          ]
        }
      },
      {
        "_index": "documents",
        "_id": "2",
        "_score": 1.5495327,
        "_source": {
          "title": "テクノロジーと教育の融合",
          "created_by": "user-1"
        },
        "highlight": {
          "content": [
            "現代の教育では、<em>テ</em><em>ク</em><em>ノ</em>ロジーがますます重要な役割を果たしています。",
            "<em>テ</em><em>ク</em><em>ノ</em>ロジーと教育の融合は、教育の質とアクセス性を向上させるための重要な手段です。"
          ]
        }
      },
      {
        "_index": "documents",
        "_id": "3",
        "_score": 1.0947267,
        "_source": {
          "title": "リモートワークの未来",
          "created_by": "user-1"
        },
        "highlight": {
          "content": [
            "これらの課題を克服するために、企業は柔軟な労働政策や適切な<em>テ</em><em>ク</em><em>ノ</em>ロジーの導入を検討する必要があります。"
          ]
        }
      }
    ]
  }
}

「テクノ」という3文字でこの並びで存在しているドキュメントのみがヒットするようになりました。

ついでに、ハイライトの部分が1文字ずつに分かれているので、これもまとめるようにしてみます。

こちらは、mapping と検索クエリを少しいじる必要があります。

      ...
      "content": {
        "type": "text",
        "analyzer": "custom_analyzer",
        "search_analyzer": "custom_analyzer",
        "term_vector": "with_positions_offsets", // mapping のここを追加
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      ...

検索

GET /documents/_search
{
  "query": {
    "match_phrase": {
      "content": {
        "query": "テクノ"
      }
    }
  },
  "_source": [
    "title",
    "created_by"
  ],
  "highlight": {
    "fields": {
      "content": {
        "matched_fields": [
          "content"
        ],
        "type": "fvh"
      }
    }
  }
}

結果

{
  "took": 17,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 3,
      "relation": "eq"
    },
    "max_score": 1.7986114,
    "hits": [
      {
        "_index": "documents",
        "_id": "4",
        "_score": 1.7986114,
        "_source": {
          "title": "グリーンテクノロジーと持続可能性",
          "created_by": "user-2"
        },
        "highlight": {
          "content": [
            "グリーン<em>テクノ</em>ロジーは、環境への負荷を最小限に抑えるための技術革新を指します。再生可能エネルギー、エネルギー効率の向上、廃棄物のリサイクルなど、様々な分野でグリーン<em>テクノ</em>ロジーの進化が進んでいます。こ",
            "といった課題に対処するための解決策が提供されています。持続可能な未来を実現するためには、グリーン<em>テクノ</em>ロジーの積極的な採用が不可欠です。"
          ]
        }
      },
      {
        "_index": "documents",
        "_id": "2",
        "_score": 1.5495327,
        "_source": {
          "title": "テクノロジーと教育の融合",
          "created_by": "user-1"
        },
        "highlight": {
          "content": [
            "現代の教育では、<em>テクノ</em>ロジーがますます重要な役割を果たしています。インタラクティブな学習アプリケーションやオンライン教材を活用することで、生徒たちはより効果的に学び、自分のペースで進歩することができま",
            "データ分析ツールを使用して生徒の進歩を追跡し、個々のニーズに合った指導を提供することができます。<em>テクノ</em>ロジーと教育の融合は、教育の質とアクセス性を向上させるための重要な手段です。"
          ]
        }
      },
      {
        "_index": "documents",
        "_id": "3",
        "_score": 1.0947267,
        "_source": {
          "title": "リモートワークの未来",
          "created_by": "user-1"
        },
        "highlight": {
          "content": [
            "や労働時間の管理などの課題もあります。これらの課題を克服するために、企業は柔軟な労働政策や適切な<em>テクノ</em>ロジーの導入を検討する必要があります。"
          ]
        }
      }
    ]
  }
}

ハイライトをまとめることができました。

おわりに

入力したテキストのインデックス登録のされ方の肝となるアナライザーについて見てみました。
アナライザー次第でテキストの認識のされ方が結構変わります。
アナライザーとそれに適した検索クエリを色々試してみると、狙った検索に近づくかもしれません。