# 画面設計書 27-複数検索テンプレート

## 概要

本ドキュメントは、OpenSearchのMulti Search Template API（`_msearch/template`）エンドポイントに関する画面設計書である。1回のHTTPリクエストで複数の検索テンプレートを一括実行し、それぞれの検索結果をまとめて返却する。

### 本画面の処理概要

Multi Search Template APIは、複数の検索テンプレートリクエストを1つのHTTPリクエストにバンドルして送信し、各検索結果を配列形式で返却するAPIである。

**業務上の目的・背景**：ダッシュボード等で複数の定型検索を同時実行する場合に、テンプレート化された検索クエリをまとめて実行できる。Multi Search API（No.22）とSearch Template API（No.26）の組み合わせにより、HTTPオーバーヘッドの削減とクエリの再利用性の両立を実現する。

**画面へのアクセス方法**：HTTPクライアントから `GET/POST /_msearch/template` または `GET/POST /{index}/_msearch/template` エンドポイントにNDJSON形式のリクエストボディを送信する。

**主要な操作・処理内容**：
1. NDJSON形式のリクエストボディを解析し、メタデータ行とテンプレート本体行のペアを抽出する
2. 各ペアからSearchTemplateRequestを構築する
3. 各テンプレートを展開し、検索クエリを生成して並行実行する
4. 全検索結果を配列にまとめて返却する

**画面遷移**：個別テンプレート検索はSearch Template API（No.26）と同じ処理パス。Multi Search API（No.22）のテンプレート版である。

**権限による表示制御**：各検索リクエストに対して個別にインデックスレベルの権限チェックが行われる。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 21 | マルチサーチ | 主機能 | 1リクエストで複数の検索テンプレートを実行する処理 |
| 80 | Mustacheテンプレート | 補助機能 | Mustacheテンプレートのレンダリング処理 |

## 画面種別

API（複数テンプレート検索一括実行・結果返却）

## URL/ルーティング

| メソッド | パス | 説明 |
|---------|------|------|
| GET/POST | `/_msearch/template` | デフォルトインデックスなしで複数テンプレート検索 |
| GET/POST | `/{index}/_msearch/template` | デフォルトインデックスを指定して複数テンプレート検索 |

## 入出力項目

### URLパスパラメータ

| パラメータ | 型 | 必須 | 説明 |
|-----------|------|------|------|
| index | list | No | デフォルトとして使用するインデックス名（カンマ区切り） |

### クエリパラメータ

| パラメータ | 型 | デフォルト | 説明 |
|-----------|------|-----------|------|
| search_type | enum | query_then_fetch | 検索操作タイプ |
| typed_keys | boolean | false | 集計・サジェスタ名にタイプをプレフィックスするか |
| max_concurrent_searches | number | - | 同時実行する最大検索数 |
| rest_total_hits_as_int | boolean | false | hits.totalを整数として返却するか |
| ccs_minimize_roundtrips | boolean | true | クロスクラスタ検索のラウンドトリップを最小化するか |

### リクエストボディ（NDJSON形式、必須）

メタデータ行とテンプレート本体行のペアをnewlineで区切って繰り返す。

```
{"index": "index1"}
{"id": "template1", "params": {"query_string": "search text"}}
{"index": "index2"}
{"source": {"query": {"match": {"{{field}}": "{{value}}"}}}, "params": {"field": "title", "value": "test"}}
```

## 表示項目

### レスポンスボディ

| フィールド | 型 | 説明 |
|-----------|------|------|
| responses | array | 各テンプレート検索のレスポンス配列 |
| responses[].took | number | 各検索にかかった時間（ミリ秒） |
| responses[].hits | object | 検索結果 |
| responses[].status | number | HTTPステータスコード |
| responses[].error | object | エラー情報（エラー発生時） |

## イベント仕様

### 1-複数テンプレート検索リクエスト実行

1. `RestMultiSearchTemplateAction.prepareRequest()`がリクエストを受信（行89）
2. `parseRequest()`でNDJSONボディを解析し`MultiSearchTemplateRequest`を構築（行90）
3. `RestMultiSearchAction.parseMultiLineRequest()`で各行ペアを解析（行103-106）
4. 各ペアから`SearchTemplateRequest.fromXContent()`でテンプレートリクエストを構築（行108）
5. テンプレートにscriptが必須であることをバリデーション（行109, 118）
6. 検索パイプラインが指定されている場合はSearchRequestに設定（行111-114）
7. `MultiSearchTemplateAction`を実行（行91）

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 複数テンプレート検索実行 | Luceneインデックス | SELECT | 各テンプレートから生成されたクエリで検索 |

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

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

| 操作 | 項目 | 更新値・取得条件 | 備考 |
|-----|------|-----------------|------|
| SELECT | ドキュメント全体 | 各テンプレートから生成されたQuery DSL条件に基づく | 書き込み操作は発生しない |

## メッセージ仕様

| 種別 | メッセージ | 発生条件 |
|------|----------|----------|
| 成功 | HTTPステータス200 + 検索結果配列JSON | 正常に全テンプレート検索が完了した場合 |
| エラー | `Malformed search template` | テンプレートにscriptが含まれていない場合 |

## 例外処理

| 例外 | HTTPステータス | 説明 |
|------|--------------|------|
| IllegalArgumentException | 400 | テンプレートの形式が不正な場合 |
| ResourceNotFoundException | 404 | 保存済みテンプレートが見つからない場合 |

## 備考

- テンプレートにscript（source/id）が必須。scriptがnullの場合は`Malformed search template`エラー（RestMultiSearchTemplateAction 行109, 118）
- `RestMultiSearchAction.parseMultiLineRequest()`を再利用してNDJSONパースを行う（行103-106）
- `RestSearchAction.checkRestTotalHits()`が各リクエストに対して呼び出される（行120）
- search_pipelineは各テンプレートリクエストレベルで個別に指定可能（行111-114）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | MultiSearchTemplateRequest.java | `modules/lang-mustache/src/main/java/org/opensearch/script/mustache/MultiSearchTemplateRequest.java` | 複数テンプレートリクエストのコンテナ構造 |
| 1-2 | SearchTemplateRequest.java | `modules/lang-mustache/src/main/java/org/opensearch/script/mustache/SearchTemplateRequest.java` | 個別テンプレートリクエストの構造 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RestMultiSearchTemplateAction.java | `modules/lang-mustache/src/main/java/org/opensearch/script/mustache/RestMultiSearchTemplateAction.java` | RESTハンドラとNDJSONパース処理 |

**主要処理フロー**:
1. **行72-80**: `routes()`で4パターンのルートを登録
2. **行89-91**: `prepareRequest()`でリクエスト解析とアクション実行
3. **行97-124**: `parseRequest()`でNDJSONのパースとバリデーション
4. **行108-120**: 各テンプレートのscriptバリデーションとsearch_pipeline設定

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

```
RestMultiSearchTemplateAction.prepareRequest()
    |
    +-- parseRequest()
    |       +-- RestMultiSearchAction.parseMultiLineRequest()
    |       |       +-- SearchTemplateRequest.fromXContent() [各ペア]
    |       +-- RestSearchAction.checkRestTotalHits() [各リクエスト]
    |
    +-- client.execute(MultiSearchTemplateAction)
            +-- TransportMultiSearchTemplateAction.doExecute()
                    +-- SearchTemplateAction [各テンプレート展開・検索]
```

### データフロー図

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

HTTP Request        -->  RestMultiSearchTemplateAction       -->  HTTP Response (JSON)
  - NDJSON body             |                                      { "responses": [...] }
  (メタデータ+テンプレート     +-- parseMultiLineRequest()
   のペア繰り返し)            +-- 各テンプレート展開・検索
                            +-- 結果配列に集約
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RestMultiSearchTemplateAction.java | `modules/lang-mustache/src/main/java/org/opensearch/script/mustache/RestMultiSearchTemplateAction.java` | ソース | RESTエンドポイントハンドラ |
| MultiSearchTemplateRequest.java | `modules/lang-mustache/src/main/java/org/opensearch/script/mustache/MultiSearchTemplateRequest.java` | ソース | 複数テンプレートリクエストデータモデル |
| SearchTemplateRequest.java | `modules/lang-mustache/src/main/java/org/opensearch/script/mustache/SearchTemplateRequest.java` | ソース | テンプレートリクエストデータモデル |
| RestMultiSearchAction.java | `server/src/main/java/org/opensearch/rest/action/search/RestMultiSearchAction.java` | ソース | NDJSONパース処理の再利用元 |
| msearch_template.json | `rest-api-spec/src/main/resources/rest-api-spec/api/msearch_template.json` | 設定 | REST API仕様定義 |
