# 画面設計書 9-ドキュメント削除

## 概要

OpenSearchインデックスからドキュメントを削除するREST APIエンドポイント（DELETE /{index}/_doc/{id}）の設計書である。指定したインデックスとIDに対応するドキュメントを削除し、結果をJSON形式で返却する。

### 本画面の処理概要

本APIは、ドキュメントIDを指定してインデックスからドキュメントを削除する機能を提供する。

**業務上の目的・背景**：データのライフサイクル管理として、不要になったドキュメントや誤って登録されたドキュメントを個別に削除する必要がある。GDPR等のデータ保護規制に基づく個人データの削除要求への対応や、テストデータのクリーンアップなどのユースケースで使用される。楽観的排他制御（if_seq_no/if_primary_term）を使用することで、安全な削除が可能である。

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

**主要な操作・処理内容**：
1. クライアントからDELETEリクエストを受信する
2. インデックス名、ドキュメントID、各種パラメータを解析する
3. ドキュメントの削除操作を実行する
4. 結果（削除の成否、バージョン情報等）をJSON形式で返却する

**画面遷移**：ドキュメント取得API（GET /{index}/_doc/{id}）で存在を確認した後に本APIで削除する操作が想定される。削除後にドキュメント取得APIを呼び出すと404が返却される。

**権限による表示制御**：インデックスへの削除権限が必要。セキュリティプラグイン使用時はインデックス単位のアクセス制御が適用される。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 12 | ドキュメント削除 | 主機能 | IDを指定してドキュメントを削除する主処理 |

## 画面種別

削除（更新系API）

## URL/ルーティング

| メソッド | パス | 説明 |
|---------|------|------|
| DELETE | `/{index}/_doc/{id}` | ドキュメントを削除する |

## 入出力項目

### パスパラメータ

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

### クエリパラメータ

| パラメータ名 | 型 | 必須 | デフォルト | 説明 |
|-------------|-----|------|----------|------|
| wait_for_active_shards | string | いいえ | 1 | 処理前にアクティブである必要があるシャードコピー数 |
| refresh | enum (true, false, wait_for) | いいえ | false | trueでリフレッシュ実行、wait_forでリフレッシュ待機 |
| routing | string | いいえ | - | ルーティング値 |
| timeout | time | いいえ | 1m | 操作タイムアウト |
| if_seq_no | number | いいえ | - | 楽観的排他制御用シーケンス番号 |
| if_primary_term | number | いいえ | - | 楽観的排他制御用プライマリターム |
| version | number | いいえ | - | 楽観的排他制御用バージョン番号 |
| version_type | enum (internal, external, external_gte, force) | いいえ | internal | バージョンタイプ |

### レスポンスボディ

| フィールド名 | 型 | 説明 |
|-------------|-----|------|
| _index | string | インデックス名 |
| _id | string | ドキュメントID |
| _version | number | ドキュメントバージョン |
| result | string | 操作結果（"deleted" または "not_found"） |
| _shards | object | シャード情報 |
| _shards.total | number | 総シャード数 |
| _shards.successful | number | 成功シャード数 |
| _shards.failed | number | 失敗シャード数 |
| _seq_no | number | シーケンス番号 |
| _primary_term | number | プライマリターム |

## 表示項目

レスポンスのJSON全フィールドが表示項目となる（上記レスポンスボディの項目を参照）。

## イベント仕様

### 1-ドキュメント削除

1. DELETE `/{index}/_doc/{id}` リクエストを受信する
2. `RestDeleteAction.prepareRequest()` がリクエストパラメータを解析する（69-85行目）
3. `DeleteRequest` オブジェクトを構築する
4. `client.delete()` で削除操作を実行する（84行目）
5. 結果をJSON形式で返却する
   - ドキュメントが存在し削除された場合：result="deleted"、HTTP 200
   - ドキュメントが存在しなかった場合：result="not_found"、HTTP 404

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ドキュメント削除 | 指定インデックス | DELETE | 指定IDのドキュメントを論理削除する |

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

#### 指定インデックス

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | _id | パスパラメータのid | 削除対象のドキュメント識別子 |
| DELETE | _version | インクリメントされたバージョン番号 | 削除操作もバージョンが更新される |
| DELETE | _seq_no | 新しいシーケンス番号 | 削除操作の順序管理 |

## メッセージ仕様

| メッセージ種別 | HTTPステータス | 条件 | メッセージ内容 |
|--------------|--------------|------|-------------|
| 成功（削除） | 200 OK | ドキュメントが存在し削除された場合 | result: "deleted" |
| 成功（未存在） | 404 Not Found | ドキュメントが存在しなかった場合 | result: "not_found" |
| バージョン競合 | 409 Conflict | if_seq_no/if_primary_term不一致時 | VersionConflictEngineException |

## 例外処理

| 例外 | HTTPステータス | 条件 | レスポンス |
|------|--------------|------|----------|
| VersionConflictEngineException | 409 | 楽観的排他制御でバージョン不一致の場合 | バージョン競合の詳細メッセージ |
| IndexNotFoundException | 404 | インデックスが存在しない場合 | index_not_found_exception |
| ClusterBlockException | 403 | インデックスが読み取り専用の場合 | ブロック状態メッセージ |

## 備考

- ドキュメントの削除はLuceneレベルでは論理削除として処理される。物理的な削除はセグメントマージ時に実行される。
- 存在しないドキュメントのIDを指定して削除しても、エラーではなくresult="not_found"が返却される（HTTPステータスは404）。
- 削除操作でもバージョンとシーケンス番号は更新される。
- version_typeパラメータにはforceオプションが存在するが、これは内部使用向けである。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | DeleteRequest.java | `server/src/main/java/org/opensearch/action/delete/DeleteRequest.java` | リクエストフィールド（index, id, routing, timeout, version等）を理解する |
| 1-2 | DeleteResponse.java | `server/src/main/java/org/opensearch/action/delete/DeleteResponse.java` | レスポンス構造（result: DELETED/NOT_FOUND）を理解する |

**読解のコツ**: DeleteResponseはDocWriteResponseを継承しており、resultフィールドでDELETEDまたはNOT_FOUNDが設定される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RestDeleteAction.java | `server/src/main/java/org/opensearch/rest/action/document/RestDeleteAction.java` | ルーティング（60行目）、パラメータ解析（69-82行目）、クライアント実行（84行目）を確認する |

**主要処理フロー**:
1. **60行目**: DELETEメソッドで `/{index}/_doc/{id}` のルーティングを登録
2. **70行目**: DeleteRequestをindex, idで初期化
3. **71-77行目**: routing, timeout, refresh, version, versionType, if_seq_no, if_primary_termの設定
4. **79-82行目**: wait_for_active_shardsの設定
5. **84行目**: `client.delete(deleteRequest, new RestStatusToXContentListener<>(channel))` で削除実行

#### Step 3: トランスポート層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TransportDeleteAction.java | `server/src/main/java/org/opensearch/action/delete/TransportDeleteAction.java` | シャードへのルーティングと削除処理を確認する |

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

```
RestDeleteAction.prepareRequest()
    |
    +-- DeleteRequest 構築（パラメータ解析）
    |
    +-- client.delete(deleteRequest, listener)
            |
            +-- TransportDeleteAction
                    |
                    +-- TransportBulkAction（単一削除もBulk経由）
                            |
                            +-- TransportShardBulkAction
                                    |
                                    +-- InternalEngine.delete()
                                            |
                                            +-- Lucene IndexWriter.deleteDocuments()
```

### データフロー図

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

DELETE /{index}/_doc/{id}  --> RestDeleteAction             --> HTTP 200
                                 |                              {
                                 v                                "_index": "...",
                           DeleteRequest構築                       "_id": "...",
                                 |                                "result": "deleted",
                                 v                                "_shards": {...}
                           TransportDeleteAction               }
                                 |
                                 v                          --> HTTP 404
                           InternalEngine.delete()              {
                           (論理削除)                              "result": "not_found"
                                                              }
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RestDeleteAction.java | `server/src/main/java/org/opensearch/rest/action/document/RestDeleteAction.java` | ソース | RESTハンドラ（エントリーポイント） |
| DeleteRequest.java | `server/src/main/java/org/opensearch/action/delete/DeleteRequest.java` | ソース | リクエストオブジェクト |
| DeleteResponse.java | `server/src/main/java/org/opensearch/action/delete/DeleteResponse.java` | ソース | レスポンスオブジェクト |
| TransportDeleteAction.java | `server/src/main/java/org/opensearch/action/delete/TransportDeleteAction.java` | ソース | トランスポートアクション |
| delete.json | `rest-api-spec/src/main/resources/rest-api-spec/api/delete.json` | 設定 | REST API仕様定義 |
