# 機能設計書 73-韓国語アナライザ（Nori）

## 概要

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

### 本機能の処理概要

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

**業務上の目的・背景**：韓国語は膠着語であり、助詞や語尾の結合が頻繁に発生するため、標準トークナイザでは適切な単語分割ができない。Noriはmecab-ko-dicベースの形態素解析により、韓国語テキストを正確に単語単位に分割し、複合語の分解（decompound）も行う。

**機能の利用シーン**：韓国語コンテンツを含むインデックスの作成時、韓国語検索クエリの解析時に使用される。

**主要な処理内容**：
1. NoriTokenizer: mecab-ko-dicベースの韓国語形態素解析によるトークン化
2. NoriPartOfSpeechStopFilter: 品詞タグに基づくトークンフィルタリング
3. NoriReadingFormFilter: 漢字の韓国語読み変換
4. NoriNumberFilter: 韓国語数詞の正規化

**関連システム・外部連携**：Apache Lucene Nori（韓国語形態素解析ライブラリ）、mecab-ko-dic辞書。

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

## 関連画面

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

## 機能種別

テキスト解析処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| decompound_mode | String | No | 複合語分解モード（デフォルト: KoreanTokenizer.DEFAULT_DECOMPOUND） | NONE / DISCARD / MIXED |
| user_dictionary | String | No | ユーザー辞書ファイルパス | configディレクトリ相対パス |
| user_dictionary_rules | List<String> | No | インライン形式のユーザー辞書ルール | user_dictionaryと排他 |
| discard_punctuation | Boolean | No | 句読点トークンの除外（デフォルト: true） | true / false |
| stoptags | List<String> | No | フィルタ対象の品詞タグリスト | 韓国語品詞タグ |

### 入力データソース

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

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| tokens | List<Token> | 形態素解析されたトークンリスト |
| token.term | String | トークン文字列 |
| token.reading | String | 読み仮名 |
| token.position | int | トークン位置 |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. プラグインロード
   └─ AnalysisNoriPlugin.getTokenFilters/getTokenizers/getAnalyzersでコンポーネント登録
2. ファクトリ初期化
   └─ NoriTokenizerFactoryでdecompoundMode, userDictionary, discardPunctuationを設定
3. テキスト解析パイプライン実行
   └─ Tokenizer(形態素解析) → TokenFilter(品詞/読み/数詞)
```

### フローチャート

```mermaid
flowchart TD
    A[テキスト入力] --> B[NoriTokenizer / KoreanTokenizer]
    B --> C[NoriPartOfSpeechStopFilter]
    C --> D[NoriReadingFormFilter]
    D --> E[NoriNumberFilter]
    E --> F[トークン出力]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-73-01 | 辞書排他制御 | user_dictionaryとuser_dictionary_rulesの同時指定は不可 | NoriTokenizerFactory（68-71行目） |
| BR-73-02 | デフォルト分解モード | decompound_mode未指定時はKoreanTokenizer.DEFAULT_DECOMPOUND | NoriTokenizerFactory getMode()（90行目） |
| BR-73-03 | 句読点除外デフォルト | discard_punctuation未指定時はtrue | NoriTokenizerFactory（64行目） |

### 計算ロジック

特になし。形態素解析はKoreanTokenizer（Lucene）の辞書ベース分割アルゴリズムに依存する。

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

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

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

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

該当なし。

## エラー処理

### エラーケース一覧

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

### リトライ仕様

リトライは不要。

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

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

## パフォーマンス要件

形態素解析は辞書ベースの処理であり、テキスト長に比例した処理時間を要する。

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

ユーザー辞書ファイルはconfigディレクトリから読み込まれる。

## 備考

NoriプラグインはCharFilterを提供しない点がKuromojiプラグインとの構造上の違いである。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | AnalysisNoriPlugin.java | `plugins/analysis-nori/src/main/java/org/opensearch/plugin/analysis/nori/AnalysisNoriPlugin.java` | 登録コンポーネント: TokenFilter x3, Tokenizer x1, Analyzer x1 |

**読解のコツ**: Kuromojiと同様のAnalysisPlugin構造。CharFilterがない点に注意。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | NoriTokenizerFactory.java | `plugins/analysis-nori/src/main/java/org/opensearch/index/analysis/NoriTokenizerFactory.java` | decompound_mode, ユーザー辞書, discard_punctuationの設定処理 |

**主要処理フロー**:
- **60-65行目**: コンストラクタ - decompoundMode, userDictionary, discardPunctuation設定
- **67-87行目**: getUserDictionary() - ユーザー辞書読み込みとバリデーション
- **89-96行目**: getMode() - DecompoundModeのパース
- **98-107行目**: create() - KoreanTokenizerインスタンス生成

#### Step 3: アナライザプロバイダを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | NoriAnalyzerProvider.java | `plugins/analysis-nori/src/main/java/org/opensearch/index/analysis/NoriAnalyzerProvider.java` | noriアナライザの構成 |

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

```
AnalysisNoriPlugin (プラグイン登録)
    |
    +-- getAnalyzers()
    |       +-- NoriAnalyzerProvider -> KoreanAnalyzer
    |
    +-- getTokenizers()
    |       +-- NoriTokenizerFactory -> KoreanTokenizer
    |               +-- getUserDictionary() -> UserDictionary.open()
    |               +-- getMode() -> DecompoundMode
    |
    +-- getTokenFilters()
            +-- NoriPartOfSpeechStopFilterFactory
            +-- NoriReadingFormFilterFactory
            +-- NoriNumberFilterFactory
```

### データフロー図

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

韓国語テキスト ───> KoreanTokenizer ───> PartOfSpeechFilter ───> ReadingFormFilter ───> トークンリスト
                    (形態素解析/         (品詞フィルタ)          (読み変換)
                     複合語分解)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AnalysisNoriPlugin.java | `plugins/analysis-nori/src/main/java/org/opensearch/plugin/analysis/nori/AnalysisNoriPlugin.java` | ソース | プラグインエントリーポイント |
| NoriAnalyzerProvider.java | `plugins/analysis-nori/src/main/java/org/opensearch/index/analysis/NoriAnalyzerProvider.java` | ソース | Noriアナライザプロバイダ |
| NoriTokenizerFactory.java | `plugins/analysis-nori/src/main/java/org/opensearch/index/analysis/NoriTokenizerFactory.java` | ソース | トークナイザファクトリ |
| NoriPartOfSpeechStopFilterFactory.java | `plugins/analysis-nori/src/main/java/org/opensearch/index/analysis/NoriPartOfSpeechStopFilterFactory.java` | ソース | 品詞フィルタ |
| NoriReadingFormFilterFactory.java | `plugins/analysis-nori/src/main/java/org/opensearch/index/analysis/NoriReadingFormFilterFactory.java` | ソース | 読み仮名変換フィルタ |
| NoriNumberFilterFactory.java | `plugins/analysis-nori/src/main/java/org/opensearch/index/analysis/NoriNumberFilterFactory.java` | ソース | 数詞正規化フィルタ |
