# 機能設計書 25-検索サジェスト

## 概要

本ドキュメントは、OpenSearchの検索サジェスト機能に関する機能設計書である。入力補完（Completion Suggest）、スペル修正（Term/Phrase Suggest）などのサジェスト機能を定義する。

### 本機能の処理概要

**業務上の目的・背景**：ユーザーの検索体験を向上させるため、入力途中の文字列に対してサジェスト（候補提案）を行う機能が必要である。スペルミスの修正候補、類似フレーズの提案、入力補完候補の提示により、ユーザーが目的のデータに素早くたどり着けるようにする。

**機能の利用シーン**：検索ボックスでのオートコンプリート（Completion Suggest）、スペルミスの修正提案（Term Suggest）、フレーズレベルの修正提案（Phrase Suggest）、検索結果が0件の場合の「もしかして」提案などで利用される。

**主要な処理内容**：
1. SuggestBuilderを通じてサジェストリクエストを構築する
2. 3種類のサジェスター（Term、Phrase、Completion）から適切なものを選択・実行する
3. 各サジェスターがLuceneの転置インデックスを使用してサジェスト候補を生成する
4. SuggestionSearchContextに基づいて結果をスコアリング・ランキングする

**関連システム・外部連携**：検索API（SearchAction）のリクエストボディ内で`suggest`セクションとして利用される。独立したAPIエンドポイントではなく、検索リクエストの一部として動作する。

**権限による制御**：検索APIの権限（`indices:data/read/search`）に準拠する。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 21 | 検索 | 補助機能 | 検索リクエスト内のサジェスト処理 |

## 機能種別

データ検索（サジェスト・入力補完）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| text | String | No | サジェスト対象のグローバルテキスト | - |
| suggest.{name} | SuggestionBuilder | Yes | 名前付きサジェスト定義 | 少なくとも1つ必要 |
| suggest.{name}.text | String | No | 個別サジェストのテキスト（グローバルテキストを上書き） | - |
| suggest.{name}.term | Object | No | Term Suggest設定 | textとの排他 |
| suggest.{name}.phrase | Object | No | Phrase Suggest設定 | textとの排他 |
| suggest.{name}.completion | Object | No | Completion Suggest設定 | textとの排他 |
| suggest.{name}.field | String | Yes | サジェスト対象フィールド | - |
| suggest.{name}.size | int | No | 返却するサジェスト候補数 | - |

### 入力データソース

検索APIリクエストボディ内の`suggest`セクション。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| suggest | Suggest | サジェスト結果のコンテナ |
| suggest.{name} | List<Suggestion> | 名前付きサジェスト結果リスト |
| suggest.{name}[].text | String | サジェスト元テキスト |
| suggest.{name}[].options | List<Option> | サジェスト候補リスト |
| suggest.{name}[].options[].text | String | サジェスト候補テキスト |
| suggest.{name}[].options[].score | float | サジェスト候補のスコア |
| suggest.{name}[].options[].freq | int | サジェスト候補の出現頻度（Term Suggest） |

### 出力先

SearchResponseのsuggestフィールド（JSON形式）

## 処理フロー

### 処理シーケンス

```
1. SearchRequestのsuggestセクション解析
   └─ SuggestBuilder.fromXContentでパース
2. SuggestionSearchContextの構築
   └─ SuggestBuilder.build()でQueryShardContextを使用
3. 各サジェスターの実行
   └─ SuggestProcessor（推定）でサジェスト実行
4. サジェスト結果の集約
   └─ Suggestオブジェクトに結果を格納
5. SearchResponse内にサジェスト結果を含めて返却
```

### フローチャート

```mermaid
flowchart TD
    A[SearchRequest with suggest] --> B[SuggestBuilder解析]
    B --> C[SuggestionSearchContext構築]
    C --> D{サジェストタイプ判定}
    D -->|Term| E[TermSuggester実行]
    D -->|Phrase| F[PhraseSuggester実行]
    D -->|Completion| G[CompletionSuggester実行]
    E --> H[結果集約]
    F --> H
    G --> H
    H --> I[Suggest結果をSearchResponseに格納]
    I --> J[レスポンス返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-25-01 | グローバルテキスト | グローバルtextはすべてのサジェスト定義に適用される | text指定時 |
| BR-25-02 | 個別テキスト優先 | 個別サジェスト定義のtextはグローバルtextを上書きする | 個別text指定時 |
| BR-25-03 | サジェストタイプ | Term、Phrase、Completionの3種類をサポート | 常時 |

### 計算ロジック

- Term Suggest: 編集距離（Levenshtein distance）に基づくスコアリング
- Phrase Suggest: 言語モデルに基づくフレーズスコアリング
- Completion Suggest: FST（Finite State Transducer）ベースのプレフィクスマッチング

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| サジェスト | 対象インデックスの指定フィールド | SELECT | 転置インデックスまたはCompletionフィールドからサジェスト候補を取得 |

### テーブル別操作詳細

読み取り専用操作。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 400 | ParsingException | サジェスト定義のJSONパースエラー | リクエストのJSON形式を修正 |
| 400 | IllegalArgumentException | 未知のサジェストタイプ | サポートされるサジェストタイプを使用 |

### リトライ仕様

検索APIのリトライ仕様に準拠。

## トランザクション仕様

読み取り専用操作であり、トランザクション管理は不要。

## パフォーマンス要件

- Completion SuggestはインメモリのFSTデータ構造を使用し、高速な応答を実現
- Term/Phrase Suggestは転置インデックスのアクセスが必要なため、Completionより遅い場合がある

## セキュリティ考慮事項

- 検索APIの権限に準拠
- サジェスト候補にセンシティブなデータが含まれる可能性がある点に注意

## 備考

- SuggestBuilderはPublicApi(since = "1.0.0")としてマーク
- サジェストは検索リクエストのオプション機能であり、独立したAPIエンドポイントはない

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | SuggestBuilder.java | `server/src/main/java/org/opensearch/search/suggest/SuggestBuilder.java` | サジェストリクエストの構築。globalText、Map<String, SuggestionBuilder<?>> |
| 1-2 | SuggestionBuilder.java | `server/src/main/java/org/opensearch/search/suggest/SuggestionBuilder.java` | サジェスト定義の抽象基底クラス |
| 1-3 | Suggest.java | `server/src/main/java/org/opensearch/search/suggest/Suggest.java` | サジェスト結果のコンテナ |

**読解のコツ**: SuggestBuilderの67-70行目でGLOBAL_TEXT_FIELDとsuggestionsマップの構造を理解すること。

#### Step 2: サジェストタイプ別の実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | DirectSpellcheckerSettings.java | `server/src/main/java/org/opensearch/search/suggest/DirectSpellcheckerSettings.java` | スペルチェック設定 |
| 2-2 | term/ | `server/src/main/java/org/opensearch/search/suggest/term/` | Term Suggest実装 |
| 2-3 | phrase/ | `server/src/main/java/org/opensearch/search/suggest/phrase/` | Phrase Suggest実装 |
| 2-4 | completion/ | `server/src/main/java/org/opensearch/search/suggest/completion/` | Completion Suggest実装 |

#### Step 3: サジェスト実行の流れを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | SuggestionSearchContext.java | `server/src/main/java/org/opensearch/search/suggest/SuggestionSearchContext.java` | サジェスト実行コンテキスト |
| 3-2 | Suggester.java | `server/src/main/java/org/opensearch/search/suggest/Suggester.java` | サジェスターインターフェース |
| 3-3 | SuggestProcessor.java | `server/src/main/java/org/opensearch/search/suggest/SuggestProcessor.java` | サジェスト処理プロセッサ |

### プログラム呼び出し階層図

```
SearchRequest.source().suggest()
    |
    +-- SuggestBuilder
            |
            +-- SuggestionBuilder<?> (term/phrase/completion)
                    |
                    +-- build(QueryShardContext) -> SuggestionContext
                            |
                            +-- Suggester.execute()
                                    |
                                    +-- Lucene DirectSpellChecker (Term)
                                    +-- Lucene PhraseSuggester (Phrase)
                                    +-- Lucene CompletionSuggester (Completion)
```

### データフロー図

```
[入力]                    [処理]                        [出力]

suggest: {            SuggestBuilder.build()         Suggest
  "my-suggest": {         |                           |
    "text": "...",    SuggestionSearchContext      suggest: {
    "term": {             |                         "my-suggest": [
      "field": "..."  Suggester.execute()             { text, options[] }
    }                     |                          ]
  }                   Lucene Index Access           }
}
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| SuggestBuilder.java | `server/src/main/java/org/opensearch/search/suggest/SuggestBuilder.java` | ソース | サジェストリクエスト構築 |
| SuggestBuilders.java | `server/src/main/java/org/opensearch/search/suggest/SuggestBuilders.java` | ソース | サジェストビルダーファクトリ |
| SuggestionBuilder.java | `server/src/main/java/org/opensearch/search/suggest/SuggestionBuilder.java` | ソース | サジェスト定義抽象基底 |
| Suggest.java | `server/src/main/java/org/opensearch/search/suggest/Suggest.java` | ソース | サジェスト結果コンテナ |
| Suggester.java | `server/src/main/java/org/opensearch/search/suggest/Suggester.java` | ソース | サジェスターインターフェース |
| SuggestionSearchContext.java | `server/src/main/java/org/opensearch/search/suggest/SuggestionSearchContext.java` | ソース | サジェスト実行コンテキスト |
| SuggestProcessor.java | `server/src/main/java/org/opensearch/search/suggest/SuggestProcessor.java` | ソース | サジェスト処理プロセッサ |
| DirectSpellcheckerSettings.java | `server/src/main/java/org/opensearch/search/suggest/DirectSpellcheckerSettings.java` | ソース | スペルチェック設定 |
| SortBy.java | `server/src/main/java/org/opensearch/search/suggest/SortBy.java` | ソース | サジェストソート基準 |
