# 機能設計書 72-日本語アナライザ（Kuromoji）

## 概要

本ドキュメントは、OpenSearchの日本語アナライザプラグイン（analysis-kuromoji）の機能設計について記述する。Apache Lucene Kuromojiを基盤とした日本語形態素解析機能を提供するプラグインである。

### 本機能の処理概要

Kuromojiプラグインは、日本語テキストの形態素解析を行い、適切なトークン化、読み仮名変換、品詞フィルタリング、カタカナ語ステミング等の日本語固有の処理を提供する。

**業務上の目的・背景**：日本語は空白区切りがなく、標準的なトークナイザでは正しく単語分割ができない。Kuromojiは辞書ベースの形態素解析により、日本語テキストを適切に単語単位に分割し、全文検索の精度を大幅に向上させる。

**機能の利用シーン**：日本語コンテンツを含むインデックスの作成時に使用される。検索クエリの解析、オートコンプリート用のKuromoji Completionアナライザ、インデックス設定でのアナライザ指定時に利用される。

**主要な処理内容**：
1. KuromojiTokenizer: MeCab辞書（IPADIC）ベースの日本語形態素解析によるトークン化
2. KuromojiBaseFormFilter: 動詞・形容詞の基本形への変換
3. KuromojiPartOfSpeechFilter: 品詞タグに基づくトークンフィルタリング
4. KuromojiReadingFormFilter: 漢字の読み仮名（カタカナ/ローマ字）変換
5. KuromojiKatakanaStemmer: カタカナ語の長音記号ステミング
6. KuromojiNumberFilter: 漢数字のアラビア数字変換
7. KuromojiCompletionFilter: オートコンプリート用のローマ字変換フィルタ
8. JapaneseStopFilter: 日本語ストップワードフィルタ
9. KuromojiIterationMarkCharFilter: 繰り返し記号（々、ゝ等）の展開

**関連システム・外部連携**：Apache Lucene Kuromoji（日本語形態素解析ライブラリ）、IPADIC辞書。

**権限による制御**：インデックス作成権限を持つユーザーがアナライザを指定する。特別な権限制御はない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 55 | アナライズ | 参照画面 | テキストに対してKuromoji解析プロセスを実行しトークン分解を返す処理 |

## 機能種別

テキスト解析処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| mode | String | No | トークナイザの分割モード（デフォルト: search） | search / normal / extended |
| user_dictionary | String | No | ユーザー辞書ファイルパス | configディレクトリ相対パス |
| user_dictionary_rules | List<String> | No | インライン形式のユーザー辞書ルール | CSV形式（user_dictionaryと排他） |
| discard_punctuation | Boolean | No | 句読点トークンの除外（デフォルト: true） | true / false |
| nbest_cost | int | No | N-best候補のコスト閾値 | 整数値（デフォルト: -1） |
| nbest_examples | String | No | N-best候補のサンプル文 | テキスト文字列 |
| discard_compound_token | Boolean | No | 複合トークンの除外（デフォルト: false） | true / false |
| stoptags | List<String> | No | フィルタ対象の品詞タグリスト | IPADIC品詞タグ |
| stopwords | List<String>/String | No | ストップワードリスト | 単語リストまたは_japanese_デフォルト |

### 入力データソース

インデックス設定（index settings）のanalyzerセクション、またはAnalyze APIのリクエストボディ。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| tokens | List<Token> | 形態素解析されたトークンリスト |
| token.term | String | トークン文字列（基本形変換後の場合あり） |
| token.reading | String | 読み仮名 |
| token.partOfSpeech | String | 品詞情報 |
| token.position | int | トークン位置 |

### 出力先

Luceneインデックスの転置インデックス（インデックス時）、またはAnalyze APIのレスポンス（解析時）。

## 処理フロー

### 処理シーケンス

```
1. プラグインロード
   └─ AnalysisKuromojiPlugin.getCharFilters/getTokenFilters/getTokenizers/getAnalyzersでコンポーネント登録
2. ファクトリ初期化
   └─ KuromojiTokenizerFactoryでmode, userDictionary, discardPunctuation等を設定
3. テキスト解析パイプライン実行
   └─ CharFilter(繰り返し記号展開) → Tokenizer(形態素解析) → TokenFilter(基本形/品詞/読み/ステミング)
```

### フローチャート

```mermaid
flowchart TD
    A[テキスト入力] --> B[KuromojiIterationMarkCharFilter]
    B --> C[KuromojiTokenizer / JapaneseTokenizer]
    C --> D[KuromojiBaseFormFilter]
    D --> E[KuromojiPartOfSpeechFilter]
    E --> F[JapaneseStopFilter]
    F --> G{追加フィルタ}
    G -->|reading| H[KuromojiReadingFormFilter]
    G -->|stemmer| I[KuromojiKatakanaStemmer]
    G -->|number| J[KuromojiNumberFilter]
    G -->|completion| K[KuromojiCompletionFilter]
    H --> L[トークン出力]
    I --> L
    J --> L
    K --> L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-72-01 | 辞書排他制御 | user_dictionaryとuser_dictionary_rulesの同時指定は不可 | KuromojiTokenizerFactory（92-96行目） |
| BR-72-02 | 重複エントリ禁止 | ユーザー辞書内の重複エントリはエラー | KuromojiTokenizerFactory parse()（85-87行目） |
| BR-72-03 | デフォルトモード | mode未指定時はJapaneseTokenizer.DEFAULT_MODE | KuromojiTokenizerFactory getMode()（122行目） |
| BR-72-04 | デフォルトストップワード | stopwords未指定時はJapaneseAnalyzer.getDefaultStopSet() | KuromojiAnalyzerProvider（51行目） |

### 計算ロジック

N-bestコスト計算: nbest_examples指定時、サンプル文からN-bestコストを算出し、nbest_costとのmax値を使用（KuromojiTokenizerFactory 140-142行目）。

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| テキスト解析 | Luceneインデックス | 処理のみ | 形態素解析結果はインデックス書き込み時に転置インデックスに格納 |

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

本機能は直接的なデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| IllegalArgumentException | 設定エラー | user_dictionaryとuser_dictionary_rulesの同時指定 | どちらか一方のみ指定 |
| IllegalArgumentException | 辞書エラー | ユーザー辞書CSV形式不正 | CSV形式を修正 |
| IllegalArgumentException | 辞書エラー | ユーザー辞書の重複エントリ | 重複エントリを除去 |
| OpenSearchException | ファイルエラー | ユーザー辞書ファイル読み込み失敗 | ファイルパスとパーミッションを確認 |

### リトライ仕様

リトライは不要。設定・辞書エラーはインデックス作成時に即座にエラーを返す。

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

テキスト解析はステートレス処理であり、トランザクション管理は不要。

## パフォーマンス要件

形態素解析はViterbiアルゴリズムに基づく辞書参照処理であり、テキスト長に比例した処理時間を要する。N-best解析有効時は追加のコスト計算が発生する。

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

ユーザー辞書ファイルはconfigディレクトリから読み込まれる。ファイルシステムアクセスは設定ディレクトリに制限される。

## 備考

Kuromojiプラグインは2つのアナライザを提供する: `kuromoji`（標準形態素解析）と`kuromoji_completion`（オートコンプリート用）。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | AnalysisKuromojiPlugin.java | `plugins/analysis-kuromoji/src/main/java/org/opensearch/plugin/analysis/kuromoji/AnalysisKuromojiPlugin.java` | 登録される全コンポーネント一覧。CharFilter x1, TokenFilter x7, Tokenizer x1, Analyzer x2 |

**読解のコツ**: AnalysisPluginのgetXxx()メソッドのreturn値でコンポーネント名とファクトリの対応を確認する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | KuromojiAnalyzerProvider.java | `plugins/analysis-kuromoji/src/main/java/org/opensearch/index/analysis/KuromojiAnalyzerProvider.java` | kuromojiアナライザの構成。JapaneseAnalyzerの生成パラメータ |

**主要処理フロー**:
1. **51行目**: ストップワードのパース（デフォルト: JapaneseAnalyzer.getDefaultStopSet()）
2. **52行目**: トークナイザモードの取得
3. **53行目**: ユーザー辞書の読み込み
4. **54行目**: JapaneseAnalyzerのインスタンス生成

#### Step 3: トークナイザファクトリを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | KuromojiTokenizerFactory.java | `plugins/analysis-kuromoji/src/main/java/org/opensearch/index/analysis/KuromojiTokenizerFactory.java` | トークナイザのコア設定処理。ユーザー辞書読み込み、モード設定、N-best設定 |

**主要処理フロー**:
- **70-78行目**: コンストラクタ - mode, userDictionary, discardPunctuation, nBestCost, nBestExamples, discardCompoundTokenを設定
- **91-119行目**: getUserDictionary() - ユーザー辞書のパースとバリデーション
- **121-134行目**: getMode() - search/normal/extendedモード解析
- **137-145行目**: create() - JapaneseTokenizerインスタンス生成

#### Step 4: 各フィルタを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | KuromojiBaseFormFilterFactory.java | `plugins/analysis-kuromoji/src/main/java/org/opensearch/index/analysis/KuromojiBaseFormFilterFactory.java` | 基本形変換フィルタ |
| 4-2 | KuromojiPartOfSpeechFilterFactory.java | `plugins/analysis-kuromoji/src/main/java/org/opensearch/index/analysis/KuromojiPartOfSpeechFilterFactory.java` | 品詞フィルタ |
| 4-3 | KuromojiReadingFormFilterFactory.java | `plugins/analysis-kuromoji/src/main/java/org/opensearch/index/analysis/KuromojiReadingFormFilterFactory.java` | 読み仮名変換フィルタ |
| 4-4 | JapaneseStopTokenFilterFactory.java | `plugins/analysis-kuromoji/src/main/java/org/opensearch/index/analysis/JapaneseStopTokenFilterFactory.java` | 日本語ストップワードフィルタ |

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

```
AnalysisKuromojiPlugin (プラグイン登録)
    |
    +-- getAnalyzers()
    |       +-- KuromojiAnalyzerProvider -> JapaneseAnalyzer
    |       +-- KuromojiCompletionAnalyzerProvider
    |
    +-- getCharFilters()
    |       +-- KuromojiIterationMarkCharFilterFactory
    |
    +-- getTokenizers()
    |       +-- KuromojiTokenizerFactory -> JapaneseTokenizer
    |               +-- getUserDictionary() -> UserDictionary.open()
    |               +-- getMode() -> JapaneseTokenizer.Mode
    |
    +-- getTokenFilters()
            +-- KuromojiBaseFormFilterFactory
            +-- KuromojiPartOfSpeechFilterFactory
            +-- KuromojiReadingFormFilterFactory
            +-- KuromojiKatakanaStemmerFactory
            +-- JapaneseStopTokenFilterFactory
            +-- KuromojiNumberFilterFactory
            +-- KuromojiCompletionFilterFactory
```

### データフロー図

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

日本語テキスト ───> IterationMarkCharFilter ───> JapaneseTokenizer ───> BaseFormFilter ───> トークンリスト
                    (繰り返し記号展開)          (形態素解析)          (基本形変換)
                                                                      PartOfSpeechFilter
                                                                      (品詞フィルタ)
                                                                      StopFilter
                                                                      (ストップワード除外)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AnalysisKuromojiPlugin.java | `plugins/analysis-kuromoji/src/main/java/org/opensearch/plugin/analysis/kuromoji/AnalysisKuromojiPlugin.java` | ソース | プラグインエントリーポイント |
| KuromojiAnalyzerProvider.java | `plugins/analysis-kuromoji/src/main/java/org/opensearch/index/analysis/KuromojiAnalyzerProvider.java` | ソース | Kuromojiアナライザプロバイダ |
| KuromojiTokenizerFactory.java | `plugins/analysis-kuromoji/src/main/java/org/opensearch/index/analysis/KuromojiTokenizerFactory.java` | ソース | トークナイザファクトリ |
| KuromojiBaseFormFilterFactory.java | `plugins/analysis-kuromoji/src/main/java/org/opensearch/index/analysis/KuromojiBaseFormFilterFactory.java` | ソース | 基本形変換フィルタ |
| KuromojiPartOfSpeechFilterFactory.java | `plugins/analysis-kuromoji/src/main/java/org/opensearch/index/analysis/KuromojiPartOfSpeechFilterFactory.java` | ソース | 品詞フィルタ |
| KuromojiReadingFormFilterFactory.java | `plugins/analysis-kuromoji/src/main/java/org/opensearch/index/analysis/KuromojiReadingFormFilterFactory.java` | ソース | 読み仮名変換フィルタ |
| KuromojiKatakanaStemmerFactory.java | `plugins/analysis-kuromoji/src/main/java/org/opensearch/index/analysis/KuromojiKatakanaStemmerFactory.java` | ソース | カタカナステマーフィルタ |
| KuromojiNumberFilterFactory.java | `plugins/analysis-kuromoji/src/main/java/org/opensearch/index/analysis/KuromojiNumberFilterFactory.java` | ソース | 漢数字変換フィルタ |
| KuromojiCompletionFilterFactory.java | `plugins/analysis-kuromoji/src/main/java/org/opensearch/index/analysis/KuromojiCompletionFilterFactory.java` | ソース | オートコンプリートフィルタ |
| KuromojiCompletionAnalyzerProvider.java | `plugins/analysis-kuromoji/src/main/java/org/opensearch/index/analysis/KuromojiCompletionAnalyzerProvider.java` | ソース | コンプリーションアナライザ |
| JapaneseStopTokenFilterFactory.java | `plugins/analysis-kuromoji/src/main/java/org/opensearch/index/analysis/JapaneseStopTokenFilterFactory.java` | ソース | 日本語ストップワードフィルタ |
| KuromojiIterationMarkCharFilterFactory.java | `plugins/analysis-kuromoji/src/main/java/org/opensearch/index/analysis/KuromojiIterationMarkCharFilterFactory.java` | ソース | 繰り返し記号チャーフィルタ |
