# 機能設計書 30-TermVectors API

## 概要

本ドキュメントは、OpenSearchのTermVectors API機能に関する機能設計書である。ドキュメントの転置インデックス情報（タームベクトル）を取得する機能を定義する。

### 本機能の処理概要

**業務上の目的・背景**：検索エンジンの内部的な転置インデックスの状態を確認したい場合がある。TermVectors APIは特定ドキュメントの各フィールドについて、ターム（単語）ごとの出現頻度（TF）、文書頻度（DF）、位置情報（positions）、オフセット情報（offsets）、ペイロード情報（payloads）を取得できる。これにより、テキスト解析の結果確認やスコアリングのデバッグが可能になる。

**機能の利用シーン**：テキスト解析結果の確認（どのようにテキストがトークン化されたか）、TF-IDFやBM25スコアリングのデバッグ、カスタムアナライザの動作確認、類似ドキュメント検索（More Like This）の基礎データ取得などで利用される。

**主要な処理内容**：
1. 対象インデックス・ドキュメントIDを指定してTermVectorsリクエストを構築する
2. または、仮想ドキュメント（doc）を指定してリアルタイムにターム分析を行う
3. TransportSingleShardActionとして該当シャードでTermVectorsServiceを呼び出す
4. Luceneの転置インデックスからターム情報を抽出して返却する

**関連システム・外部連携**：IndicesService/IndexShardを介してLuceneインデックスにアクセスする。TermVectorsServiceがターム情報の抽出を担当する。MultiTermVectors APIにより複数ドキュメントの一括取得もサポートする。

**権限による制御**：`indices:data/read/tv`アクション名で権限が制御される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 19 | Term Vectors | 主画面 | ドキュメントのフィールドにおけるterms情報と統計を返す主処理 |
| 20 | Multi Term Vectors | 主画面 | 1リクエストで複数のtermvectorsを一括取得する処理 |

## 機能種別

データ取得（転置インデックス情報の取得）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| index | String | Yes | 対象インデックス名 | null不可 |
| id | String | Conditional | ドキュメントID（docが未指定の場合は必須） | - |
| doc | BytesReference | No | 仮想ドキュメント（インデックスに存在しないドキュメントのターム分析） | - |
| fields | String[] | No | 取得対象フィールド | - |
| offsets | boolean | No | オフセット情報を含めるか | デフォルト: true |
| positions | boolean | No | 位置情報を含めるか | デフォルト: true |
| payloads | boolean | No | ペイロード情報を含めるか | デフォルト: true |
| term_statistics | boolean | No | ターム統計（TF, DF）を含めるか | デフォルト: false |
| field_statistics | boolean | No | フィールド統計を含めるか | デフォルト: true |
| dfs | boolean | No | 分散TF/DFを使用するか | デフォルト: false |
| routing | String | No | ルーティング値 | - |
| preference | String | No | シャード優先指定 | - |
| realtime | boolean | No | リアルタイム取得 | デフォルト: true |
| version | long | No | ドキュメントバージョン | - |
| version_type | VersionType | No | バージョンタイプ | - |
| filter | TermVectorsFilter | No | タームフィルタ条件 | - |

### 入力データソース

REST APIエンドポイント（`GET /{index}/_termvectors/{id}`, `POST /{index}/_termvectors/{id}`, `POST /{index}/_termvectors`）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| _index | String | インデックス名 |
| _id | String | ドキュメントID |
| _version | long | ドキュメントバージョン |
| found | boolean | ドキュメントが見つかったか |
| took | long | 実行時間（ミリ秒） |
| term_vectors | Map<String, TermVectorField> | フィールドごとのタームベクトル |
| term_vectors.{field}.field_statistics | FieldStatistics | フィールド統計 |
| term_vectors.{field}.terms | Map<String, TermInfo> | ターム情報のマップ |
| term_vectors.{field}.terms.{term}.term_freq | int | ドキュメント内出現頻度 |
| term_vectors.{field}.terms.{term}.doc_freq | int | 文書頻度 |
| term_vectors.{field}.terms.{term}.ttf | long | 全文書での総出現頻度 |
| term_vectors.{field}.terms.{term}.tokens | TokenInfo[] | 位置・オフセット情報 |

### 出力先

REST APIレスポンス（JSON形式）

## 処理フロー

### 処理シーケンス

```
1. リクエストバリデーション
   └─ index必須チェック
2. シャードルーティング解決
   └─ docが指定され、routingが未指定の場合はランダムシャード選択
   └─ それ以外はIDベースのルーティング
3. ルーティング解決とルーティング必須チェック
   └─ エイリアスのルーティング解決、ルーティング必須チェック
4. シャードでの実行
   └─ realtime=trueの場合はリフレッシュ待ちなしで即座に実行
   └─ realtime=falseの場合はawaitShardSearchActiveで待機
5. TermVectorsService.getTermVectors()
   └─ Lucene IndexReaderからターム情報を抽出
6. TermVectorsResponseとして返却
```

### フローチャート

```mermaid
flowchart TD
    A[TermVectorsRequest] --> B{doc指定?}
    B -->|Yes + routing無| C[ランダムシャード選択]
    B -->|No or routing有| D[IDベースルーティング]
    C --> E[シャードでshardOperation実行]
    D --> E
    E --> F{realtime?}
    F -->|Yes| G[即座にTermVectorsService呼び出し]
    F -->|No| H[awaitShardSearchActive]
    H --> G
    G --> I[TermVectorsService.getTermVectors]
    I --> J[Lucene IndexReaderからターム情報抽出]
    J --> K[TermVectorsResponse返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-30-01 | 仮想ドキュメント | docパラメータで仮想ドキュメントを指定可能。インデックスに登録されていなくてもターム分析が可能 | doc指定時 |
| BR-30-02 | リアルタイムモード | realtime=true（デフォルト）の場合、リフレッシュを待たずに最新データを取得 | realtime=true |
| BR-30-03 | セグメントレプリケーション対応 | セグメントレプリケーションが有効でrealtimeリクエストの場合、プライマリシャードを優先 | seg_rep有効 + realtime |
| BR-30-04 | ルーティング | doc指定時にroutingが未指定の場合、ランダムシャードが選択される | doc指定 + routing未指定 |

### 計算ロジック

- term_freq: ドキュメント内でのターム出現回数
- doc_freq: 当該タームを含むドキュメント数
- ttf: 全ドキュメントでの当該ターム総出現回数

## データベース操作仕様

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ターム情報取得 | 対象インデックスのLucene転置インデックス | SELECT | 転置インデックスからターム情報を抽出 |

### テーブル別操作詳細

読み取り専用操作。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 400 | ActionRequestValidationException | indexが未指定 | index名を指定する |
| 400 | RoutingMissingException | ルーティング必須なのに未指定 | routingを指定する |
| 404 | found=false | ドキュメントが存在しない | ドキュメントIDを確認する |

### リトライ仕様

TransportSingleShardActionのリトライ仕様に準拠（シャードレプリカへのフォールバック）。

## トランザクション仕様

読み取り専用操作であり、トランザクション管理は不要。

## パフォーマンス要件

- GETスレッドプール（ThreadPool.Names.GET）で実行される
- 検索スロットル設定のインデックスでは、SEARCH_THROTTLEDスレッドプールで実行される
- realtime=trueはリフレッシュを待たないため高速

## セキュリティ考慮事項

- アクション名`indices:data/read/tv`による権限制御
- ドキュメント内容がターム情報から推測可能なため、フィールドレベルセキュリティに注意

## 備考

- PublicApi(since = "1.0.0")としてマーク
- RealtimeRequestインターフェースを実装
- MultiTermVectorsActionで複数ドキュメントの一括取得が可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | TermVectorsRequest.java | `server/src/main/java/org/opensearch/action/termvectors/TermVectorsRequest.java` | id, doc, fields, offsets, positions, payloads, dfs等のフィールド。RealtimeRequestインターフェース実装 |
| 1-2 | TermVectorsResponse.java | `server/src/main/java/org/opensearch/action/termvectors/TermVectorsResponse.java` | レスポンス構造。found, index, id, version, termVectorFields |
| 1-3 | TermVectorsFields.java | `server/src/main/java/org/opensearch/action/termvectors/TermVectorsFields.java` | タームベクトルフィールドのデータ構造 |
| 1-4 | TermVectorsFilter.java | `server/src/main/java/org/opensearch/action/termvectors/TermVectorsFilter.java` | タームフィルタ条件 |

**読解のコツ**: TermVectorsRequestの82-93行目でParsable fieldsが定義されている。INDEX, ID, ROUTING, VERSION等の標準フィールドに加え、OFFSETS, POSITIONS, PAYLOADS, DFS, FILTER, DOC等のTermVectors固有パラメータが定義されている。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | TermVectorsAction.java | `server/src/main/java/org/opensearch/action/termvectors/TermVectorsAction.java` | アクション定義。NAME = "indices:data/read/tv" |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TransportTermVectorsAction.java | `server/src/main/java/org/opensearch/action/termvectors/TransportTermVectorsAction.java` | シャードルーティングとTermVectorsService呼び出し |

**主要処理フロー**:
- **90-109行目**: shards - doc指定時のランダムシャード選択、IDベースルーティング
- **92-98行目**: セグメントレプリケーション対応のプライマリ優先
- **117-124行目**: resolveRequest - ルーティング解決と必須チェック
- **127-142行目**: asyncShardOperation - realtime判定とawaitShardSearchActive
- **145-149行目**: shardOperation - TermVectorsService.getTermVectors()呼び出し
- **157-162行目**: getExecutor - スロットルインデックス対応

#### Step 4: タームベクトルサービスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | TermVectorsService.java | `server/src/main/java/org/opensearch/index/termvectors/TermVectorsService.java` | Luceneからのターム情報抽出ロジック |

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

```
REST (/_termvectors)
    |
    +-- TransportTermVectorsAction.doExecute()
            |
            +-- shards() [シャードルーティング解決]
            |       |
            |       +-- doc指定: ランダムシャード
            |       +-- ID指定: IDベースルーティング
            |
            +-- resolveRequest() [ルーティング解決]
            |
            +-- asyncShardOperation()
            |       |
            |       +-- realtime: 直接実行
            |       +-- !realtime: awaitShardSearchActive
            |
            +-- shardOperation()
                    |
                    +-- TermVectorsService.getTermVectors()
                            |
                            +-- Lucene IndexReader
                            +-- TermVectorsFields
```

### データフロー図

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

TermVectorsRequest ──> シャードルーティング ──────> TermVectorsResponse
  (index, id/doc,        |                          (found,
   fields, options)      v                           term_vectors: {
                    IndexShard                         "field": {
                         |                               "terms": {
                    TermVectorsService                     "term": {
                         |                                   term_freq,
                    Lucene IndexReader                       doc_freq,
                         |                                   tokens[]
                    TermVectorsFields                       }
                                                         }
                                                       }
                                                     })
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| TermVectorsAction.java | `server/src/main/java/org/opensearch/action/termvectors/TermVectorsAction.java` | ソース | アクション型定義 |
| TermVectorsRequest.java | `server/src/main/java/org/opensearch/action/termvectors/TermVectorsRequest.java` | ソース | リクエストモデル |
| TermVectorsResponse.java | `server/src/main/java/org/opensearch/action/termvectors/TermVectorsResponse.java` | ソース | レスポンスモデル |
| TransportTermVectorsAction.java | `server/src/main/java/org/opensearch/action/termvectors/TransportTermVectorsAction.java` | ソース | トランスポート層実行ロジック |
| TermVectorsFields.java | `server/src/main/java/org/opensearch/action/termvectors/TermVectorsFields.java` | ソース | タームベクトルフィールド |
| TermVectorsFilter.java | `server/src/main/java/org/opensearch/action/termvectors/TermVectorsFilter.java` | ソース | タームフィルタ |
| TermVectorsWriter.java | `server/src/main/java/org/opensearch/action/termvectors/TermVectorsWriter.java` | ソース | タームベクトル書き出し |
| MultiTermVectorsAction.java | `server/src/main/java/org/opensearch/action/termvectors/MultiTermVectorsAction.java` | ソース | マルチTermVectorsアクション |
| MultiTermVectorsRequest.java | `server/src/main/java/org/opensearch/action/termvectors/MultiTermVectorsRequest.java` | ソース | マルチリクエスト |
| MultiTermVectorsResponse.java | `server/src/main/java/org/opensearch/action/termvectors/MultiTermVectorsResponse.java` | ソース | マルチレスポンス |
| TransportMultiTermVectorsAction.java | `server/src/main/java/org/opensearch/action/termvectors/TransportMultiTermVectorsAction.java` | ソース | マルチTermVectorsトランスポート |
| TermVectorsService.java | `server/src/main/java/org/opensearch/index/termvectors/TermVectorsService.java` | ソース | ターム情報抽出サービス |
