# 機能設計書 11-データフィルタリング

## 概要

本ドキュメントは、Nushellにおけるデータフィルタリング機能の設計について記述する。where、filter、findコマンドを通じて、リストやテーブルから条件に合致するデータを絞り込む機能を提供する。

### 本機能の処理概要

データフィルタリング機能は、パイプラインを流れる構造化データ（リスト、テーブル、レンジなど）に対して、ユーザーが指定した条件に基づいてデータを絞り込む処理を行う。

**業務上の目的・背景**：シェル環境において、大量のデータから必要な情報のみを抽出することは日常的な作業である。従来のシェルではテキストベースのgrepやawkを使用するが、Nushellでは構造化データに対してより直感的で型安全なフィルタリングを提供する。これにより、データ分析やシステム管理作業の効率が大幅に向上する。

**機能の利用シーン**：
- `ls | where type == file` でファイルのみを表示
- `ps | where cpu > 50` でCPU使用率が高いプロセスを検出
- `[1, 2, 3, 4, 5] | where $it > 2` でリストから条件に合う値を抽出
- `find` コマンドで正規表現によるテキスト検索とハイライト表示

**主要な処理内容**：
1. 入力データ（リスト、テーブル、レンジ）をイテレータとして取得
2. 各要素に対してクロージャまたは行条件を評価
3. 条件がtrueを返す要素のみを出力に含める
4. findコマンドでは正規表現マッチングとハイライト処理を実行

**関連システム・外部連携**：パイプライン処理システム（nu-protocol, nu-engine）と連携。findコマンドはfancy_regexクレートを使用して正規表現処理を行う。

**権限による制御**：特になし。データフィルタリングはユーザー権限に依存しない純粋なデータ操作。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | メインREPL | 主画面 | フィルタリングコマンドの入力と結果表示 |

## 機能種別

データ操作（フィルタリング処理）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| condition | Closure/RowCondition | Yes (where/filter) | フィルタ条件を定義するクロージャまたは行条件 | 有効なクロージャまたは行条件式 |
| rest | Value[] | Yes (find) | 検索対象の値（複数指定可能） | - |
| --regex, -r | String | No (find) | 正規表現パターン | 有効な正規表現 |
| --ignore-case, -i | Switch | No (find) | 大文字小文字を区別しない | - |
| --multiline, -m | Switch | No (find) | 複数行モード | - |
| --dotall, -s | Switch | No (find) | ドットが改行にマッチ | - |
| --columns, -c | List | No (find) | 検索対象カラム | 文字列のリスト |
| --no-highlight, -n | Switch | No (find) | ハイライト無効化 | - |
| --invert, -v | Switch | No (find) | マッチを反転 | - |
| --rfind, -R | Switch | No (find) | 末尾から検索 | - |

### 入力データソース

- パイプライン入力: List、Table、Range、ByteStream
- 入力型は `PipelineData` として受け取り、イテレータに変換

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| filtered_data | List/Table | 条件に合致した要素のリスト |
| highlighted_data | List | (find) ハイライト付きの文字列リスト |

### 出力先

- パイプライン出力: `PipelineData`として後続コマンドへ渡す
- 画面表示: テーブル形式またはリスト形式で表示

## 処理フロー

### 処理シーケンス

```
1. コマンド引数の解析
   └─ クロージャ/条件式/正規表現パターンを取得

2. 入力データの取得
   └─ PipelineDataをイテレータに変換

3. 各要素に対してフィルタリング処理
   └─ where/filter: クロージャを評価しtrue/falseを判定
   └─ find: 正規表現マッチングまたは値の完全一致を判定

4. 条件に合致した要素の収集
   └─ filter_map等を使用して条件一致の要素のみ抽出

5. (find) ハイライト処理
   └─ マッチした部分にANSIエスケープシーケンスを付与

6. 結果をPipelineDataとして返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[引数解析]
    B --> C{コマンド種別}
    C -->|where/filter| D[クロージャ取得]
    C -->|find| E[正規表現パターン生成]
    D --> F[入力データ取得]
    E --> F
    F --> G[イテレータ変換]
    G --> H{次の要素あり?}
    H -->|Yes| I[条件評価]
    I --> J{条件一致?}
    J -->|Yes| K[結果に追加]
    J -->|No| H
    K --> L{find & ハイライト有効?}
    L -->|Yes| M[ハイライト処理]
    L -->|No| H
    M --> H
    H -->|No| N[PipelineData生成]
    N --> O[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | NULL除外 | `filter`はデフォルトでNothing値を除外 | keep-emptyフラグなしの場合 |
| BR-02 | 反転マッチ | `--invert`指定時は条件不一致の要素を返す | findコマンドで--invertフラグ指定時 |
| BR-03 | 大文字小文字 | `--ignore-case`指定時は大文字小文字を区別しない | findコマンドで-iフラグ指定時 |
| BR-04 | 行条件展開 | whereの左辺フィールド名は自動的に`$it.`を付与 | whereコマンドの行条件使用時 |

### 計算ロジック

findコマンドの正規表現生成ロジック:
- 複数の検索語はOR条件(`|`)で結合
- 特殊文字は自動エスケープ
- `--ignore-case`指定時は`(?i)`プレフィックスを追加
- `--dotall`指定時は`(?s)`プレフィックスを追加

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

該当なし（インメモリ処理のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| TypeMismatch | 型エラー | 無効な正規表現パターン | 正規表現構文を修正 |
| IncompatibleParametersSingle | パラメータエラー | --regexと検索語の同時指定 | どちらか一方のみ指定 |
| PipelineEmpty | 入力エラー | 空のパイプライン入力 | 有効な入力データを提供 |
| UnsupportedInput | 入力エラー | ByteStreamで--multiline指定 | collectで変換後に使用 |

### リトライ仕様

該当なし（同期処理のため）

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

該当なし（状態変更を伴わない）

## パフォーマンス要件

- ストリーミング処理: 大量データでもメモリ効率的に処理
- 遅延評価: イテレータベースの処理で必要な要素のみ評価
- 正規表現キャッシュ: 同一パターンの再コンパイル回避

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

- クロージャ実行: ユーザー定義クロージャはサンドボックス内で実行
- 正規表現DoS: fancy_regexライブラリによるReDoS対策

## 備考

- `filter`コマンドは0.105.0で非推奨となり、`where`の使用が推奨される
- `where`は行条件構文をサポートし、より簡潔な記述が可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | find.rs | `crates/nu-command/src/filters/find.rs` | MatchPattern構造体(288-313行目)でfindの検索パターン設定を理解 |

**読解のコツ**: `MatchPattern`構造体がfindコマンドの動作を決定する。`regex`, `search_terms`, `invert`, `highlight`等のフィールドを確認する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | where_.rs | `crates/nu-command/src/filters/where_.rs` | Whereコマンドのrun関数(57-82行目)でフィルタリングの基本処理を理解 |
| 2-2 | filter.rs | `crates/nu-command/src/filters/filter.rs` | FilterコマンドはWhereに委譲(49-51行目) |
| 2-3 | find.rs | `crates/nu-command/src/filters/find.rs` | Findコマンドのrun関数(255-286行目) |

**主要処理フロー**:
1. **64-65行目** (where_.rs): クロージャの取得とClosureEvalの初期化
2. **70-81行目** (where_.rs): `into_iter_strict`でイテレータ化し、`filter_map`で条件評価
3. **77行目** (where_.rs): `is_true()`でクロージャ結果をブール値として評価

#### Step 3: 正規表現マッチング処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | find.rs | `crates/nu-command/src/filters/find.rs` | `get_match_pattern_from_arguments`関数(315-415行目)でパターン構築を理解 |
| 3-2 | find.rs | `crates/nu-command/src/filters/find.rs` | `find_in_pipelinedata`関数(528-586行目)で実際のフィルタリング処理を理解 |

**主要処理フロー**:
- **342-398行目**: 正規表現文字列の構築（フラグ処理含む）
- **400-403行目**: fancy_regex::Regexのコンパイル
- **544-549行目**: PipelineData::Value用のフィルタ処理
- **554-563行目**: ListStream用のストリーミングフィルタ処理

#### Step 4: ハイライト処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | find.rs | `crates/nu-command/src/filters/find.rs` | `highlight_matches_in_string`関数(419-431行目) |
| 4-2 | find.rs | `crates/nu-command/src/filters/find.rs` | `highlight_all_matches`関数(452-489行目)で全マッチのハイライト処理 |

**主要処理フロー**:
- **467-479行目**: ANSIスタイルを使用してマッチ部分をハイライト
- **491-526行目**: `highlight_matches_in_value`で再帰的にRecord/Listを処理

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

```
Where::run() / Filter::run() / Find::run()
    │
    ├─ Where: ClosureEval::new()
    │      └─ input.into_iter_strict()
    │             └─ filter_map() + closure.run_with_value()
    │
    └─ Find: get_match_pattern_from_arguments()
           │
           └─ find_in_pipelinedata()
                  ├─ input.filter() / stream.modify()
                  │      └─ value_should_be_printed()
                  │             └─ string_should_be_printed()
                  │                    └─ pattern.regex.is_match()
                  │
                  └─ highlight_matches_in_value()
                         └─ highlight_matches_in_string()
                                └─ highlight_all_matches() / highlight_last_match()
```

### データフロー図

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

PipelineData ───────▶ into_iter_strict() ───▶ Iterator<Value>
     │                                              │
     │                                              ▼
     │                                     ┌─────────────────┐
     │                                     │ for each value  │
     │                                     │   ├─ evaluate   │
     │                                     │   │   condition │
     │                                     │   └─ keep if    │
     │                                     │       true      │
     │                                     └─────────────────┘
     │                                              │
     │                                              ▼
     │                                     ┌─────────────────┐
     │                     (find only)     │ highlight_      │
     │                     ─────────────▶  │ matches_in_     │
     │                                     │ value()         │
     │                                     └─────────────────┘
     │                                              │
     │                                              ▼
     └──────────────────────────────────▶ PipelineData (filtered)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| where_.rs | `crates/nu-command/src/filters/where_.rs` | ソース | whereコマンド実装 |
| filter.rs | `crates/nu-command/src/filters/filter.rs` | ソース | filterコマンド実装(非推奨) |
| find.rs | `crates/nu-command/src/filters/find.rs` | ソース | findコマンド実装 |
| mod.rs | `crates/nu-command/src/filters/mod.rs` | ソース | フィルターモジュールエクスポート |
| closure.rs | `crates/nu-engine/src/closure.rs` | ソース | クロージャ評価ロジック |
| pipeline_data.rs | `crates/nu-protocol/src/pipeline/pipeline_data.rs` | ソース | パイプラインデータ型定義 |
