# 画面設計書 32-スクロール検索

## 概要

本ドキュメントは、OpenSearchのScroll APIエンドポイントに関する画面設計書である。大量の検索結果を効率的に分割取得するためのスクロール検索機能を提供するREST APIインターフェースを定義する。

### 本画面の処理概要

本APIは、初回検索で取得したスクロールコンテキストを使用して、大量の検索結果を複数回のリクエストに分けて段階的に取得する機能を提供する。

**業務上の目的・背景**：通常の検索APIでは一度に取得できる件数に制限があるため、大量のドキュメントを全件取得する必要がある場合（データエクスポート、バッチ処理、reindexの内部処理等）にスクロール検索を使用する。スクロール検索は検索時点のスナップショットに対して動作するため、検索中のデータ変更の影響を受けない一貫した結果セットを保証する。

**画面へのアクセス方法**：HTTPクライアントから `GET/POST /_search/scroll` エンドポイントにリクエストを送信する。事前に検索API（`/{index}/_search?scroll=1m`）で`scroll_id`を取得しておく必要がある。

**主要な操作・処理内容**：
1. 初回検索で取得した`scroll_id`を指定して次のバッチ結果を取得する
2. `scroll`パラメータで検索コンテキストの存続時間を指定・延長する
3. 結果が空になるまでスクロールを繰り返し、全結果を取得する
4. 使用完了後はスクロールクリアAPI（No.33）でリソースを解放する

**画面遷移**：検索API（No.21）で`scroll`パラメータ付きの初回検索を実行後に本APIを使用する。全結果取得後はスクロールクリアAPI（No.33）でコンテキストを解放する。

**権限による表示制御**：初回検索で対象としたインデックスに対する読み取り権限が必要である。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 22 | スクロール検索 | 主機能 | 大量の結果をスクロール検索で分割取得する主処理 |

## 画面種別

API実行（検索結果ページング）

## URL/ルーティング

| メソッド | パス | 説明 |
|---------|------|------|
| GET/POST | `/_search/scroll` | スクロール検索の次バッチ取得 |
| GET/POST | `/_search/scroll/{scroll_id}` | スクロール検索（非推奨：scroll_idはボディで指定） |

## 入出力項目

### パスパラメータ

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|------|------|------|
| scroll_id | string | いいえ | スクロールID（非推奨、ボディでの指定を推奨） |

### クエリパラメータ

| パラメータ名 | 型 | デフォルト値 | 説明 |
|-------------|------|------------|------|
| scroll | time | - | スクロール検索コンテキストの維持時間 |
| scroll_id | string | - | スクロールID |
| rest_total_hits_as_int | boolean | false | hits.totalを整数として返すか |

### リクエストボディ

| フィールド名 | 型 | 必須 | 説明 |
|-------------|------|------|------|
| scroll_id | string | はい | スクロールID（ボディでの指定を推奨） |
| scroll | string | いいえ | スクロールコンテキスト維持時間 |

## 表示項目

### レスポンス

| フィールド名 | 型 | 説明 |
|-------------|------|------|
| _scroll_id | string | 次回リクエスト用のスクロールID |
| took | integer | 処理にかかった時間（ミリ秒） |
| timed_out | boolean | タイムアウトしたか |
| _shards | object | シャード統計情報 |
| hits | object | 検索結果ヒット情報 |
| hits.total | object/integer | 総ヒット件数 |
| hits.hits | array | ドキュメントの配列 |

## イベント仕様

### 1-スクロール検索実行

1. `RestSearchScrollAction.prepareRequest()`がリクエストを受け取る（行79）
2. `scroll_id`パラメータまたはボディから`SearchScrollRequest`を生成する（行80-97）
3. `scroll`パラメータが指定されている場合、Scrollオブジェクトを設定する（行84-86）
4. ボディがある場合は`fromXContent()`でパースし、ボディの値が優先される（行88-97）
5. `client.searchScroll()`で次のバッチ結果を取得する（行98）

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| スクロール検索 | なし | SELECT（読み取りのみ） | 検索コンテキストから次バッチの結果を取得 |

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

本APIは既存のスクロールコンテキストから結果を取得するのみであり、インデックスデータへの書き込み・更新は発生しない。ただし、スクロールコンテキスト自体はクラスタのメモリ上に保持される。

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|--------------|---------|
| - | 成功 | 検索結果（hits配列含む） | 正常にスクロール結果が取得された場合 |
| - | 成功 | 空のhits配列 | スクロールの最後（全結果取得済み）に到達した場合 |
| - | エラー | SearchContextMissingException | scroll_idが無効または期限切れの場合 |

## 例外処理

| 例外 | HTTPステータス | 説明 |
|------|--------------|------|
| SearchContextMissingException | 404 | スクロールコンテキストが存在しないまたは期限切れの場合 |
| IllegalArgumentException | 400 | リクエストボディのパースに失敗した場合 |
| 権限不足 | 403 | アクセス権限がない場合 |

## 備考

- URLパスでのscroll_id指定は7.0.0で非推奨。ボディでの指定を推奨
- スクロール検索はリアルタイム検索ではなく、初回検索時点のスナップショットに対して動作する
- スクロールコンテキストはメモリを消費するため、使用後は必ずスクロールクリアAPI（No.33）で解放すること
- `scroll`パラメータで指定した時間が経過すると、コンテキストは自動的に削除される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | SearchScrollRequest.java | `server/src/main/java/org/opensearch/action/search/SearchScrollRequest.java` | scroll_idとscroll時間のフィールド定義、fromXContent()メソッド |
| 1-2 | Scroll.java | `server/src/main/java/org/opensearch/search/Scroll.java` | スクロール検索の時間保持オブジェクト |

**読解のコツ**: `SearchScrollRequest`は通常の`SearchRequest`とは異なり、スクロールIDと存続時間のみを保持するシンプルな構造である。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RestSearchScrollAction.java | `server/src/main/java/org/opensearch/rest/action/search/RestSearchScrollAction.java` | RESTハンドラの処理フロー |

**主要処理フロー**:
1. **行67-76**: ルーティング定義（4パス、うち2つは非推奨）
2. **行79-98**: prepareRequest()でリクエスト解析とTransport層への委譲
3. **行80-82**: scroll_idパラメータの取得とSearchScrollRequest生成
4. **行84-86**: scrollパラメータのパースとScroll設定
5. **行88-97**: ボディからのパース（ボディが優先）
6. **行98**: client.searchScroll()呼び出し

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TransportSearchScrollAction.java | `server/src/main/java/org/opensearch/action/search/TransportSearchScrollAction.java` | スクロールコンテキストからの結果取得 |

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

```
RestSearchScrollAction.prepareRequest()
    |
    +-- SearchScrollRequest生成
    |      +-- scrollId設定（パラメータまたはボディ）
    |      +-- Scroll設定（keepAlive時間）
    |
    +-- client.searchScroll()
           +-- TransportSearchScrollAction
                  +-- SearchContext取得
                  +-- 次バッチ結果フェッチ
                  +-- SearchResponse返却
```

### データフロー図

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

HTTPリクエスト ──────> RestSearchScrollAction ──────> JSON レスポンス
(GET/POST)           ├─ scroll_id解析                 ├─ _scroll_id
├─ scroll_id         ├─ scroll時間設定                ├─ took
├─ scroll            └─> TransportSearchScrollAction  ├─ hits.total
                          ├─ SearchContext参照          └─ hits.hits[]
                          └─ 次バッチ結果取得
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RestSearchScrollAction.java | `server/src/main/java/org/opensearch/rest/action/search/RestSearchScrollAction.java` | ソース | RESTエンドポイントハンドラ |
| TransportSearchScrollAction.java | `server/src/main/java/org/opensearch/action/search/TransportSearchScrollAction.java` | ソース | トランスポート層アクション |
| SearchScrollRequest.java | `server/src/main/java/org/opensearch/action/search/SearchScrollRequest.java` | ソース | リクエストデータ構造 |
| Scroll.java | `server/src/main/java/org/opensearch/search/Scroll.java` | ソース | スクロール時間設定 |
| scroll.json | `rest-api-spec/src/main/resources/rest-api-spec/api/scroll.json` | 設定 | REST API仕様定義 |
| RestSearchScrollActionTests.java | `server/src/test/java/org/opensearch/search/scroll/RestSearchScrollActionTests.java` | テスト | RESTハンドラのユニットテスト |
