# 画面設計書 7-ドキュメント存在確認

## 概要

OpenSearchインデックスにドキュメントが存在するかを確認するREST APIエンドポイント（HEAD /{index}/_doc/{id}）の設計書である。レスポンスボディを返さず、HTTPステータスコード（200または404）でドキュメントの存在有無を判定する。

### 本画面の処理概要

本APIは、ドキュメントIDを指定してインデックスにドキュメントが存在するかどうかを確認する機能を提供する。

**業務上の目的・背景**：ドキュメントの内容を取得する必要はなく、存在有無のみを確認したい場合に使用する。HEADリクエストはレスポンスボディを返さないため、ドキュメント取得API（GET /{index}/_doc/{id}）よりもネットワーク帯域の消費が少ない。バッチ処理での存在チェックや、条件分岐の判定に適している。

**画面へのアクセス方法**：HTTPクライアントからHEADメソッドで `/{index}/_doc/{id}` にリクエストを送信する。

**主要な操作・処理内容**：
1. クライアントからHEADリクエストを受信する
2. インデックス名、ドキュメントIDを解析する
3. ドキュメントの存在をチェックする
4. 存在する場合はHTTP 200、存在しない場合はHTTP 404を返す（ボディなし）

**画面遷移**：本APIでドキュメントの存在を確認した後、ドキュメント取得API（GET /{index}/_doc/{id}）で内容を取得したり、ドキュメント削除API（DELETE /{index}/_doc/{id}）で削除する操作が想定される。

**権限による表示制御**：インデックスへの読み取り権限が必要。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 11 | ドキュメント取得 | 主機能 | ドキュメントがインデックスに存在するかをHEADリクエストで確認する処理 |

## 画面種別

存在確認（参照系API）

## URL/ルーティング

| メソッド | パス | 説明 |
|---------|------|------|
| HEAD | `/{index}/_doc/{id}` | ドキュメントの存在を確認する |

## 入出力項目

### パスパラメータ

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

### クエリパラメータ

| パラメータ名 | 型 | 必須 | デフォルト | 説明 |
|-------------|-----|------|----------|------|
| stored_fields | list | いいえ | - | 返却するストアドフィールドのカンマ区切りリスト |
| preference | string | いいえ | random | 操作を実行するノードまたはシャードの指定 |
| realtime | boolean | いいえ | true | リアルタイムモードで取得するか |
| refresh | boolean | いいえ | false | 取得前にシャードをリフレッシュする |
| routing | string | いいえ | - | ルーティング値 |
| _source | list | いいえ | - | _sourceフィールドの返却制御 |
| _source_excludes | list | いいえ | - | _sourceから除外するフィールドリスト |
| _source_includes | list | いいえ | - | _sourceから抽出するフィールドリスト |
| version | number | いいえ | - | 楽観的排他制御用バージョン番号 |
| version_type | enum (internal, external, external_gte, force) | いいえ | internal | バージョンタイプ |

### レスポンス

レスポンスボディは返却されない。HTTPステータスコードのみで結果を伝える。

| HTTPステータス | 意味 |
|--------------|------|
| 200 OK | ドキュメントが存在する |
| 404 Not Found | ドキュメントが存在しない |

## 表示項目

レスポンスボディなし。HTTPヘッダのみが返却される。

## イベント仕様

### 1-ドキュメント存在確認

1. HEAD `/{index}/_doc/{id}` リクエストを受信する
2. `RestGetAction.prepareRequest()` がリクエストパラメータを解析する（ドキュメント取得APIと同じハンドラ）
3. `GetRequest` オブジェクトを構築する
4. `client.get()` でドキュメント取得を実行する
5. `GetResponse.isExists()` でドキュメントの存在を判定する
6. 存在する場合はHTTP 200、存在しない場合はHTTP 404を返す（HEADのためボディは破棄）

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| HEAD /{index}/_doc/{id} | 指定インデックス | SELECT | ドキュメントの存在を確認する（更新なし） |

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

本APIはデータベース（インデックス）の更新を行わない。読み取り専用の操作である。

## メッセージ仕様

| メッセージ種別 | HTTPステータス | 条件 | メッセージ内容 |
|--------------|--------------|------|-------------|
| 存在 | 200 OK | ドキュメントが存在する場合 | ボディなし |
| 未存在 | 404 Not Found | ドキュメントが存在しない場合 | ボディなし |

## 例外処理

| 例外 | HTTPステータス | 条件 | レスポンス |
|------|--------------|------|----------|
| IndexNotFoundException | 404 | インデックスが存在しない場合 | ボディなし（HEADのため） |

## 備考

- 本APIはRestGetActionで処理される。GET /{index}/_doc/{id}（ドキュメント取得）とHEAD /{index}/_doc/{id}（ドキュメント存在確認）は同一のハンドラで処理され、HTTPメソッドの違いのみが動作に影響する。
- exists.jsonとして独立したAPI仕様定義が存在するが、実装上はRestGetActionの71行目で `new Route(HEAD, "/{index}/_doc/{id}")` として登録されている。
- HEADリクエストのため、レスポンスのContent-Lengthヘッダにはボディが存在した場合のサイズが設定される場合がある。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | GetRequest.java | `server/src/main/java/org/opensearch/action/get/GetRequest.java` | ドキュメント取得APIと共通のリクエスト構造 |
| 1-2 | GetResponse.java | `server/src/main/java/org/opensearch/action/get/GetResponse.java` | isExists()メソッドがHTTPステータスの判定に使用される |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RestGetAction.java | `server/src/main/java/org/opensearch/rest/action/document/RestGetAction.java` | 71行目でHEADルートが登録されていること、102-103行目でisExists()による分岐を確認する |

**主要処理フロー**:
1. **71行目**: `new Route(HEAD, "/{index}/_doc/{id}")` でHEADルートを登録
2. **76-98行目**: GETと同じパラメータ解析処理
3. **100-105行目**: client.get()の実行とレスポンスステータス判定
4. HTTPレイヤーでHEADリクエストのレスポンスボディが自動破棄

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

```
RestGetAction.prepareRequest()  [HEAD /{index}/_doc/{id}]
    |
    +-- GetRequest 構築
    +-- FetchSourceContext 設定
    |
    +-- client.get(getRequest, listener)
            |
            +-- TransportGetAction
                    |
                    +-- GetResponse
                            |
                            +-- isExists() ? HTTP 200 : HTTP 404
                                    |
                                    +-- [HTTP層でボディ破棄]
```

### データフロー図

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

HEAD /{index}/_doc/{id}  --> RestGetAction               --> HTTP 200 (存在)
                               |                              (ボディなし)
                               v
                         GetRequest構築                   --> HTTP 404 (未存在)
                               |                              (ボディなし)
                               v
                         TransportGetAction
                               |
                               v
                         GetResponse.isExists()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RestGetAction.java | `server/src/main/java/org/opensearch/rest/action/document/RestGetAction.java` | ソース | RESTハンドラ（GET/HEAD両方を処理） |
| GetRequest.java | `server/src/main/java/org/opensearch/action/get/GetRequest.java` | ソース | リクエストオブジェクト |
| GetResponse.java | `server/src/main/java/org/opensearch/action/get/GetResponse.java` | ソース | レスポンスオブジェクト |
| TransportGetAction.java | `server/src/main/java/org/opensearch/action/get/TransportGetAction.java` | ソース | トランスポートアクション |
| exists.json | `rest-api-spec/src/main/resources/rest-api-spec/api/exists.json` | 設定 | REST API仕様定義 |
