# 画面設計書 24-検索説明

## 概要

本ドキュメントは、OpenSearchのExplain API（`_explain`）エンドポイントに関する画面設計書である。Explain APIは、特定のドキュメントがクエリに一致する（または一致しない）理由とスコア計算の詳細を返す。

### 本画面の処理概要

Explain APIは、特定のドキュメントに対してクエリを適用した際のスコアリング詳細や一致/不一致の理由を返却するAPIである。

**業務上の目的・背景**：検索結果のランキングが期待通りでない場合のデバッグやチューニングに使用される。特定のドキュメントがなぜ上位に表示されるのか（またはされないのか）を詳細に分析することで、クエリやマッピングの最適化に役立つ。検索の品質向上のための開発・運用ツールとして重要である。

**画面へのアクセス方法**：HTTPクライアントから `GET/POST /{index}/_explain/{id}` エンドポイントにリクエストを送信する。インデックス名とドキュメントIDの指定が必須である。

**主要な操作・処理内容**：
1. 対象インデックスとドキュメントIDを特定する
2. クエリパラメータまたはリクエストボディからクエリ条件を構築する
3. 指定ドキュメントに対してクエリを適用し、スコア計算の詳細を取得する
4. 一致/不一致の理由とスコアの内訳を返却する

**画面遷移**：Search API（No.21）でのスコアデバッグの補助ツールとして使用される。検索結果に疑問がある場合にExplain APIで個別ドキュメントを確認する流れが一般的である。

**権限による表示制御**：対象インデックスおよびドキュメントへの読み取り権限が必要である。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 27 | Explain API | 主機能 | 特定ドキュメントがクエリに一致する理由とスコア計算根拠を返す処理 |

## 画面種別

API（検索スコア説明）

## URL/ルーティング

| メソッド | パス | 説明 |
|---------|------|------|
| GET/POST | `/{index}/_explain/{id}` | 指定ドキュメントのクエリ一致理由を返す |

## 入出力項目

### URLパスパラメータ

| パラメータ | 型 | 必須 | 説明 |
|-----------|------|------|------|
| index | string | Yes | インデックス名 |
| id | string | Yes | ドキュメントID |

### クエリパラメータ

| パラメータ | 型 | デフォルト | 説明 |
|-----------|------|-----------|------|
| q | string | - | Luceneクエリ文字列構文によるクエリ |
| analyzer | string | - | クエリ文字列で使用するアナライザ |
| analyze_wildcard | boolean | false | ワイルドカード・プレフィックスクエリを分析するか |
| default_operator | enum (AND/OR) | OR | クエリ文字列のデフォルト演算子 |
| df | string | _all | デフォルトフィールド |
| lenient | boolean | false | フォーマットベースのクエリ失敗を無視するか |
| preference | string | random | 操作を実行するノード/シャードの優先設定 |
| routing | string | - | ルーティング値 |
| stored_fields | list | - | レスポンスに含めるストアドフィールド |
| _source | list | - | _sourceフィールドの返却制御 |
| _source_excludes | list | - | _sourceから除外するフィールド |
| _source_includes | list | - | _sourceに含めるフィールド |

### リクエストボディ（任意）

Query DSLによるクエリ定義。

## 表示項目

### レスポンスボディ

| フィールド | 型 | 説明 |
|-----------|------|------|
| _index | string | インデックス名 |
| _id | string | ドキュメントID |
| matched | boolean | クエリに一致したか |
| explanation | object | スコア説明の詳細 |
| explanation.value | number | スコア値 |
| explanation.description | string | スコア計算の説明 |
| explanation.details | array | スコア計算の内訳 |
| get | object | ドキュメントの取得結果（_source等） |

## イベント仕様

### 1-検索説明リクエスト実行

1. `RestExplainAction.prepareRequest()`がリクエストを受信（行71）
2. `ExplainRequest`を構築（インデックス名、ドキュメントID指定、行72）
3. `parent`、`routing`、`preference`を設定（行73-75）
4. リクエストボディまたはqパラメータからクエリを構築（行77-84）
5. `stored_fields`を設定（行91-97）
6. `FetchSourceContext`を設定（行99）
7. `client.explain()`でExplainアクションを実行（行101）

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 検索説明実行 | Luceneインデックス | SELECT | 指定ドキュメントに対するクエリのスコア計算詳細を取得 |

### テーブル別更新項目詳細

#### Luceneインデックス（読み取り専用）

| 操作 | 項目 | 更新値・取得条件 | 備考 |
|-----|------|-----------------|------|
| SELECT | スコア説明 | 指定index/idのドキュメントに対するクエリ評価 | 書き込み操作は発生しない |

## メッセージ仕様

| 種別 | メッセージ | 発生条件 |
|------|----------|----------|
| 成功 | HTTPステータス200 + 説明JSON | 正常にExplainが完了した場合 |
| エラー | `The parameter [fields] is no longer supported, please use [stored_fields] to retrieve stored fields` | 非推奨のfieldsパラメータが指定された場合 |

## 例外処理

| 例外 | HTTPステータス | 説明 |
|------|--------------|------|
| IndexNotFoundException | 404 | 指定されたインデックスが存在しない場合 |
| DocumentMissingException | 404 | 指定されたドキュメントが存在しない場合（matched=falseで返却） |
| IllegalArgumentException | 400 | fieldsパラメータが指定された場合 |

## 備考

- `fields`パラメータは廃止されており、`stored_fields`を使用する必要がある（RestExplainAction 行86-89）
- `parent`パラメータは明示的にサポートされているが、OpenSearchの現行バージョンでは非推奨の可能性がある（行73）
- レスポンスの`explanation`オブジェクトはLuceneのExplanation構造をそのまま反映しており、再帰的なdetails構造を持つ

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ExplainRequest.java | `server/src/main/java/org/opensearch/action/explain/ExplainRequest.java` | Explainリクエストの構造（index, id, query等） |
| 1-2 | ExplainResponse.java | `server/src/main/java/org/opensearch/action/explain/ExplainResponse.java` | Explainレスポンスの構造（matched, explanation） |

**読解のコツ**: `ExplainResponse`の`explanation`フィールドはLuceneの`Explanation`クラスをそのままシリアライズしている。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RestExplainAction.java | `server/src/main/java/org/opensearch/rest/action/search/RestExplainAction.java` | RESTハンドラ全体（103行のコンパクトな実装） |

**主要処理フロー**:
1. **行62**: `routes()`でGET/POSTの2パターンを登録
2. **行72**: `ExplainRequest`構築（index, id）
3. **行77-84**: クエリ条件の構築（ボディ優先、qパラメータフォールバック）
4. **行86-89**: fieldsパラメータの非推奨チェック
5. **行101**: `client.explain()`でExplainアクション実行

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

```
RestExplainAction.prepareRequest()
    |
    +-- ExplainRequest構築 (index, id)
    |
    +-- RestActions.getQueryContent() / urlParamsToQueryBuilder()
    |
    +-- FetchSourceContext.parseFromRestRequest()
    |
    +-- client.explain()
            +-- TransportExplainAction.doExecute()
                    +-- ShardSearchService (Lucene Explanation生成)
```

### データフロー図

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

HTTP Request        -->  RestExplainAction                 -->  HTTP Response (JSON)
  - index, id              |                                      { "matched": true/false,
  - Query DSL              +-- ExplainRequest構築                    "explanation": {...} }
                           +-- TransportExplainAction
                                Lucene Explanation生成
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RestExplainAction.java | `server/src/main/java/org/opensearch/rest/action/search/RestExplainAction.java` | ソース | RESTエンドポイントハンドラ |
| ExplainRequest.java | `server/src/main/java/org/opensearch/action/explain/ExplainRequest.java` | ソース | Explainリクエストデータモデル |
| ExplainResponse.java | `server/src/main/java/org/opensearch/action/explain/ExplainResponse.java` | ソース | Explainレスポンスデータモデル |
| explain.json | `rest-api-spec/src/main/resources/rest-api-spec/api/explain.json` | 設定 | REST API仕様定義 |
