# 画面設計書 23-ドキュメント件数

## 概要

本ドキュメントは、OpenSearchのCount API（`_count`）エンドポイントに関する画面設計書である。Count APIは、クエリに一致するドキュメントの件数のみを返却するAPIであり、検索結果の本体を取得せずにヒット数を効率的に確認できる。

### 本画面の処理概要

Count APIは、指定されたクエリ条件に一致するドキュメントの件数を返却する軽量な検索APIである。

**業務上の目的・背景**：データの件数確認やページネーションの総ページ数計算、条件に一致するデータの有無確認など、件数のみが必要な場面で使用される。Search APIで`size=0`を指定するのと同等だが、より簡潔なレスポンスを返すため、帯域幅とパース処理の節約になる。

**画面へのアクセス方法**：HTTPクライアントから `GET/POST /_count` または `GET/POST /{index}/_count` エンドポイントにリクエストを送信する。URLパラメータによる簡易クエリ（`q`パラメータ）とリクエストボディによるQuery DSLの両方に対応する。

**主要な操作・処理内容**：
1. クエリパラメータまたはリクエストボディからクエリ条件を構築する
2. 内部的にSearchRequest（size=0、trackTotalHits=true）を構築する
3. Search APIと同じ検索パスで各シャードに検索を実行する
4. ドキュメント件数、シャード情報、terminated_earlyフラグを返却する

**画面遷移**：Search API（No.21）の軽量版であり、検索結果の本体取得にはSearch APIへ遷移する。

**権限による表示制御**：Search APIと同様にインデックスレベルの権限チェックが行われる。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 20 | 検索API | 主機能 | クエリに一致するドキュメント数を返す処理 |
| 19 | 全文検索 | 補助機能 | 件数カウント対象のクエリ実行処理 |

## 画面種別

API（件数返却）

## URL/ルーティング

| メソッド | パス | 説明 |
|---------|------|------|
| GET/POST | `/_count` | 全インデックスを対象にドキュメント件数を返す |
| GET/POST | `/{index}/_count` | 指定インデックスを対象にドキュメント件数を返す |

## 入出力項目

### URLパスパラメータ

| パラメータ | 型 | 必須 | 説明 |
|-----------|------|------|------|
| index | list | No | 対象インデックス名（カンマ区切り） |

### クエリパラメータ

| パラメータ | 型 | デフォルト | 説明 |
|-----------|------|-----------|------|
| q | string | - | Luceneクエリ文字列構文によるクエリ |
| analyzer | string | - | クエリ文字列で使用するアナライザ |
| analyze_wildcard | boolean | false | ワイルドカード・プレフィックスクエリを分析するか |
| default_operator | enum (AND/OR) | OR | クエリ文字列のデフォルト演算子 |
| df | string | - | デフォルトフィールド |
| lenient | boolean | false | フォーマットベースのクエリ失敗を無視するか |
| min_score | number | -1 | 指定スコア以上のドキュメントのみカウント |
| preference | string | random | 操作を実行するノード/シャードの優先設定 |
| routing | list | - | ルーティング値 |
| terminate_after | number | - | 各シャードでカウントする最大ドキュメント数 |
| ignore_unavailable | boolean | false | 利用不可のインデックスを無視するか |
| ignore_throttled | boolean | false | スロットルされたインデックスを無視するか |
| allow_no_indices | boolean | - | ワイルドカード式が解決されない場合に無視するか |
| expand_wildcards | enum | open | ワイルドカード展開対象 |

### リクエストボディ（任意）

Query DSLによるクエリ定義（queryフィールドのみ）。

## 表示項目

### レスポンスボディ

| フィールド | 型 | 説明 |
|-----------|------|------|
| count | number | 一致するドキュメント件数 |
| terminated_early | boolean | 早期終了したか（terminate_after指定時のみ） |
| _shards | object | シャード情報 |
| _shards.total | number | 合計シャード数 |
| _shards.successful | number | 成功シャード数 |
| _shards.skipped | number | スキップシャード数 |
| _shards.failed | number | 失敗シャード数 |

## イベント仕様

### 1-件数カウントリクエスト実行

1. `RestCountAction.prepareRequest()`がリクエストを受信（行85）
2. `SearchRequest`を`size(0).trackTotalHits(true)`で構築（行88）
3. リクエストボディまたはURLパラメータからクエリを構築（行90-98）
4. `min_score`、`routing`、`preference`、`terminate_after`を設定（行100-113）
5. `client.search()`でSearch APIと同じパスで実行（行114）
6. `RestBuilderListener`でレスポンスを`count`フィールド中心のJSON形式に変換（行116-133）

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 件数カウント実行 | Luceneインデックス | SELECT | 指定条件に一致するドキュメント数をカウント |

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

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

| 操作 | 項目 | 更新値・取得条件 | 備考 |
|-----|------|-----------------|------|
| SELECT | ドキュメント件数 | Query DSL条件に基づくカウント | size=0でドキュメント本体は取得しない |

## メッセージ仕様

| 種別 | メッセージ | 発生条件 |
|------|----------|----------|
| 成功 | HTTPステータス200 + 件数JSON | 正常にカウントが完了した場合 |
| エラー | `terminateAfter must be > 0` | terminate_afterに負の値が指定された場合 |

## 例外処理

| 例外 | HTTPステータス | 説明 |
|------|--------------|------|
| IndexNotFoundException | 404 | 指定されたインデックスが存在しない場合 |
| IllegalArgumentException | 400 | terminate_afterに負の値が指定された場合 |
| QueryShardException | 400 | クエリの解析に失敗した場合 |

## 備考

- 内部的にはSearch APIを`size=0`、`trackTotalHits=true`で呼び出している（RestCountAction 行88）
- レスポンスは`count`フィールドにドキュメント件数を含むシンプルな形式で返却される
- `terminated_early`フィールドは`terminate_after`が指定された場合にのみ含まれる（行118-119）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | SearchRequest.java | `server/src/main/java/org/opensearch/action/search/SearchRequest.java` | 内部的にSearchRequestを使用（size=0設定） |
| 1-2 | SearchResponse.java | `server/src/main/java/org/opensearch/action/search/SearchResponse.java` | レスポンスからcount値を抽出するため |

**読解のコツ**: Count APIは独自のリクエスト/レスポンスクラスを持たず、SearchRequestとSearchResponseを再利用している。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RestCountAction.java | `server/src/main/java/org/opensearch/rest/action/search/RestCountAction.java` | RESTハンドラ全体（138行のコンパクトな実装） |

**主要処理フロー**:
1. **行86**: SearchRequestの構築（インデックス指定）
2. **行88**: `size(0).trackTotalHits(true)`設定が核心
3. **行90-98**: クエリ条件の構築（ボディまたはURLパラメータ）
4. **行114-135**: SearchResponseからcount値を抽出してカスタムJSON構築

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

```
RestCountAction.prepareRequest()
    |
    +-- SearchRequest構築 (size=0, trackTotalHits=true)
    |
    +-- RestActions.urlParamsToQueryBuilder() / getQueryContent()
    |
    +-- client.search()
            +-- SearchAction (Search APIと同じパス)
                    +-- TransportSearchAction.doExecute()
```

### データフロー図

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

HTTP Request        -->  RestCountAction                   -->  HTTP Response (JSON)
  - q パラメータ            |                                      { "count": N,
  または Query DSL          +-- SearchRequest(size=0)                "_shards": {...} }
                            +-- client.search()
                            +-- response.getHits()
                                .getTotalHits().value()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RestCountAction.java | `server/src/main/java/org/opensearch/rest/action/search/RestCountAction.java` | ソース | RESTエンドポイントハンドラ |
| SearchRequest.java | `server/src/main/java/org/opensearch/action/search/SearchRequest.java` | ソース | 検索リクエスト（内部利用） |
| SearchResponse.java | `server/src/main/java/org/opensearch/action/search/SearchResponse.java` | ソース | 検索レスポンス（count抽出元） |
| count.json | `rest-api-spec/src/main/resources/rest-api-spec/api/count.json` | 設定 | REST API仕様定義 |
