# 画面設計書 31-クエリバリデーション

## 概要

本ドキュメントは、OpenSearchのValidate Query APIエンドポイントに関する画面設計書である。検索クエリの構文妥当性を事前に検証し、コスト高なクエリの実行を回避するためのREST APIインターフェースを定義する。

### 本画面の処理概要

本APIは、検索クエリを実際に実行せずにその構文的・論理的な妥当性を事前検証する機能を提供する。

**業務上の目的・背景**：大規模なインデックスに対してコストの高い検索クエリを実行する前に、そのクエリが正しい構文であるか、想定通りに解釈されるかを検証することで、不要なリソース消費やエラーを未然に防止する。特に複雑なQuery DSLを構築する開発・運用フェーズで、デバッグツールとして重要な役割を果たす。

**画面へのアクセス方法**：HTTPクライアント（curl、Kibana Dev Tools、OpenSearch Dashboards等）から `GET/POST /_validate/query` または `GET/POST /{index}/_validate/query` エンドポイントにリクエストを送信する。

**主要な操作・処理内容**：
1. クエリ文字列パラメータ（`q`パラメータ）またはリクエストボディ（Query DSL）でクエリを指定し、バリデーションを実行する
2. `explain`パラメータを指定することで、エラーの詳細情報を取得する
3. `rewrite`パラメータを指定することで、Luceneが実際に実行するクエリの書き換え結果を確認する
4. `all_shards`パラメータを指定することで、全シャードでの検証を実行する

**画面遷移**：本APIは検索API（No.21）のクエリ構築工程の事前検証として使用される。バリデーション成功後に検索API（`/{index}/_search`）を実行する流れが一般的である。

**権限による表示制御**：対象インデックスに対する読み取り権限が必要である。Security Pluginが有効な場合、インデックスレベルの権限制御が適用される。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 28 | Validate API | 主機能 | 検索クエリの構文妥当性を事前検証する処理 |

## 画面種別

API実行（クエリ検証）

## URL/ルーティング

| メソッド | パス | 説明 |
|---------|------|------|
| GET/POST | `/_validate/query` | 全インデックス対象のクエリバリデーション |
| GET/POST | `/{index}/_validate/query` | 指定インデックス対象のクエリバリデーション |

## 入出力項目

### パスパラメータ

| パラメータ名 | 型 | 必須 | 説明 |
|-------------|------|------|------|
| index | list | いいえ | カンマ区切りのインデックス名リスト。`_all`または空文字で全インデックス対象 |

### クエリパラメータ

| パラメータ名 | 型 | デフォルト値 | 説明 |
|-------------|------|------------|------|
| explain | boolean | false | エラーの詳細情報を返すかどうか |
| ignore_unavailable | boolean | - | 利用不可のインデックスを無視するかどうか |
| allow_no_indices | boolean | - | ワイルドカードが具体的インデックスに解決されない場合に無視するか |
| expand_wildcards | enum | open | ワイルドカード展開の対象（open/closed/hidden/none/all） |
| q | string | - | Luceneクエリ文字列構文のクエリ |
| analyzer | string | - | クエリ文字列に使用するアナライザ |
| analyze_wildcard | boolean | false | ワイルドカード・プレフィクスクエリを解析するか |
| default_operator | enum | OR | クエリ文字列のデフォルト演算子（AND/OR） |
| df | string | - | フィールドプレフィクスがない場合のデフォルトフィールド |
| lenient | boolean | - | フォーマットベースのクエリ失敗を無視するか |
| rewrite | boolean | false | 実際のLuceneクエリの書き換え結果を表示するか |
| all_shards | boolean | false | 全シャードでバリデーションを実行するか |

### リクエストボディ

| フィールド名 | 型 | 必須 | 説明 |
|-------------|------|------|------|
| query | object | いいえ | Query DSLによるクエリ定義 |

## 表示項目

### レスポンス

| フィールド名 | 型 | 説明 |
|-------------|------|------|
| valid | boolean | クエリが有効かどうか |
| _shards | object | シャード統計情報（total/successful/failed） |
| explanations | array | explain=true時のクエリ説明情報 |
| error | string | explain=true時のエラー詳細メッセージ |

## イベント仕様

### 1-クエリバリデーション実行

クライアントがGET/POSTリクエストを送信すると、以下の処理が実行される。

1. `RestValidateQueryAction.prepareRequest()`がリクエストを受け取り、`ValidateQueryRequest`を生成する（行83-116）
2. リクエストボディまたは`q`パラメータからクエリを解析する（行93-98）
3. ボディのパースに失敗した場合は`handleException()`でエラーレスポンスを返す（行106-111）
4. 正常な場合は`TransportValidateQueryAction`にリクエストを委譲する（行113）
5. 各シャードでクエリのバリデーションが実行され、結果が集約される

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| クエリバリデーション | なし | SELECT（読み取りのみ） | クエリの妥当性検証のみでデータ変更なし |

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

本APIはクエリの妥当性を検証するのみであり、インデックスやドキュメントへの書き込み・更新は一切発生しない。

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|--------------|---------|
| - | 成功 | `{"valid": true}` | クエリが有効な場合 |
| - | エラー | `{"valid": false, "error": "..."}` | クエリが無効な場合（explain=true） |
| - | エラー | `{"valid": false}` | クエリが無効な場合（explain=false） |
| - | 例外 | ParsingException | リクエストボディのパースに失敗した場合 |

## 例外処理

| 例外 | HTTPステータス | 説明 |
|------|--------------|------|
| ParsingException | 200（valid=false） | クエリのパースエラー時、validをfalseで返却する |
| IndexNotFoundException | 404 | 指定されたインデックスが存在しない場合 |
| 権限不足 | 403 | 対象インデックスへのアクセス権限がない場合 |

## 備考

- 本APIは読み取り専用であり、クラスタの状態やインデックスデータを変更しない
- `all_shards`パラメータを使用すると全シャードでバリデーションを実行するため、レスポンスタイムが増加する可能性がある
- Luceneクエリ文字列構文とQuery DSLの両方をサポートしている

---

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

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

### 推奨読解順序

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

まず、リクエスト・レスポンスのデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ValidateQueryRequest.java | `server/src/main/java/org/opensearch/action/admin/indices/validate/query/ValidateQueryRequest.java` | バリデーションリクエストのフィールド（query, explain, rewrite, allShards等）を確認 |
| 1-2 | ValidateQueryResponse.java | `server/src/main/java/org/opensearch/action/admin/indices/validate/query/ValidateQueryResponse.java` | レスポンスのフィールド（valid, explanations, VALID_FIELD定数等）を確認 |

**読解のコツ**: `ValidateQueryRequest`は`BroadcastRequest`を継承しており、全シャードに対してブロードキャストされるリクエストパターンである。

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

REST層のハンドラを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RestValidateQueryAction.java | `server/src/main/java/org/opensearch/rest/action/admin/indices/RestValidateQueryAction.java` | RESTリクエストの受付とパース処理 |

**主要処理フロー**:
1. **行66-75**: ルーティング定義（4つのエンドポイント）
2. **行83-84**: リクエストパラメータの抽出とValidateQueryRequest生成
3. **行86-89**: explain/rewrite/allShardsパラメータの設定
4. **行93-98**: クエリボディまたはqパラメータからのクエリ解析
5. **行105-115**: エラーハンドリングまたはTransportActionへの委譲

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TransportValidateQueryAction.java | `server/src/main/java/org/opensearch/action/admin/indices/validate/query/TransportValidateQueryAction.java` | 各シャードでのクエリバリデーション実行とレスポンス集約 |

**主要処理フロー**:
- ブロードキャストパターンで各シャードにバリデーションリクエストを分散
- 各シャードでQueryParserを使用してクエリの妥当性を検証
- 結果を集約してValidateQueryResponseとして返却

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

```
RestValidateQueryAction.prepareRequest()
    |
    +-- ValidateQueryRequest生成
    |      +-- Strings.splitStringByCommaToArray() -- インデックス名解析
    |      +-- IndicesOptions.fromRequest() -- インデックスオプション設定
    |      +-- RestActions.getQueryContent() -- ボディからクエリ解析
    |      +-- RestActions.urlParamsToQueryBuilder() -- qパラメータからクエリ解析
    |
    +-- client.admin().indices().validateQuery()
           +-- TransportValidateQueryAction
                  +-- シャード別バリデーション実行
                  +-- ValidateQueryResponse集約
```

### データフロー図

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

HTTPリクエスト ──────> RestValidateQueryAction ──────> JSON レスポンス
(GET/POST)           ├─ パラメータ解析                 ├─ valid: true/false
├─ index             ├─ クエリ解析                     ├─ _shards情報
├─ query (body/q)    └─> TransportValidateQueryAction  └─ explanations
├─ explain                ├─ シャード分散                  (explain=true時)
├─ rewrite                └─ クエリ妥当性検証
└─ all_shards
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RestValidateQueryAction.java | `server/src/main/java/org/opensearch/rest/action/admin/indices/RestValidateQueryAction.java` | ソース | RESTエンドポイントハンドラ |
| TransportValidateQueryAction.java | `server/src/main/java/org/opensearch/action/admin/indices/validate/query/TransportValidateQueryAction.java` | ソース | トランスポート層アクション |
| ValidateQueryRequest.java | `server/src/main/java/org/opensearch/action/admin/indices/validate/query/ValidateQueryRequest.java` | ソース | リクエストデータ構造 |
| ValidateQueryResponse.java | `server/src/main/java/org/opensearch/action/admin/indices/validate/query/ValidateQueryResponse.java` | ソース | レスポンスデータ構造 |
| QueryExplanation.java | `server/src/main/java/org/opensearch/action/admin/indices/validate/query/QueryExplanation.java` | ソース | クエリ説明データ構造 |
| indices.validate_query.json | `rest-api-spec/src/main/resources/rest-api-spec/api/indices.validate_query.json` | 設定 | REST API仕様定義 |
| RestValidateQueryActionTests.java | `server/src/test/java/org/opensearch/rest/action/admin/indices/RestValidateQueryActionTests.java` | テスト | RESTハンドラのユニットテスト |
