概要
- jsongrep はJSONドキュメントのパス検索に特化した高速ツール
- DFA(決定性有限オートマトン) ベースの検索エンジンを採用し、O(1)でパス探索を実現
- クエリ構文 は正規表現的で、シンプルかつ直感的
- ベンチマーク で他のツール(jq等)と比較し、高速性を証明
- Rust製クロスプラットフォーム ツールとして、今後の発展が期待される
jsongrep導入と特徴
- jsongrep はJSONドキュメントのパスにマッチする値を抽出する検索ツール
- Rust製 で、クロスプラットフォーム対応(バイナリ配布あり)
- インストール は
cargo install jsongrepで簡単 - クエリ言語 はパス指定、ワイルドカード、オルタネーション(|)、再帰、オプション(?)など正規表現的な記法
- パイプ対応 や
--with-pathオプションで出力制御が可能
クエリ例
- ドット区切りでネストしたフィールド指定:
roommates[0].name
- ワイルドカードで全要素対象:
favorite_drinks[*]
- オルタネーションで複数候補:
name | roommates
- 再帰的探索:
(* | [*])*.name-F name(ショートカット)
- オプション(存在しなくてもOK):
roommates[0].favorite_food?
jsongrepの強みと弱み
-
強み
- JSONドキュメントを 木構造 としてパス探索
- クエリを DFA にコンパイルし、探索時は1回の状態遷移のみ
- O(1) で各エッジを処理、バックトラックや再帰的探索不要
- jq や jmespath 等のツールよりも検索に特化し圧倒的高速
-
弱み
- jq ほど普及していない
- クエリ言語は 変換・加工 には非対応(検索専用)
- フィルタ・演算・文字列補間 等は不可
- 新しいツールで、実運用での実績は少ない
jsongrepのDFAベース検索エンジン
- 検索エンジンのパイプライン
- JSONドキュメントを 木構造 にパース(serde_json_borrow利用)
- クエリ文字列を AST にパース(pestライブラリ)
- ASTから NFA (非決定性有限オートマトン)をGlushkov法で構築
- NFAを DFA に変換(subset construction)
- JSON木をDFAで辿り、マッチする値を収集
クエリASTの例と構文
- 構文要素
- フィールド名、配列インデックス、範囲、ワイルドカード、オプション(?)、Kleeneスター(*)、オルタネーション(|)、シーケンス(.)
- 例:
roommates[*].name→ Sequence構造のAST
JSON木構造
- オブジェクトのキーや配列インデックスが エッジ、値が ノード
- クエリは ルートから葉までのパス 集合を定義
Glushkov法によるNFA構築
- クエリを 直線化 し、各シンボルにユニークな位置番号を付与
- First/Last/Followsセット を計算し、状態遷移を決定
- ε遷移なし のNFAを生成し、後のDFA化を容易に
NFAからDFAへの変換
- subset construction (パワーセット構成法)でNFAの状態集合をDFAの1状態にマッピング
- DFAは常に1状態のみを保持し、 O(1) の遷移で探索を実現
ベンチマーク戦略と結果
- 比較対象: jq, jmespath, jsonpath-rust等
- 評価指標: パース時間、クエリコンパイル時間、検索時間、エンドツーエンド時間
- データセット: xlarge(約190MB)等、実用規模のJSON
- 結果: jsongrepは検索速度で他ツールを大きく上回る
まとめ・参考情報
- jsongrep は検索特化で設計された、 高速・シンプル なJSONパス探索ツール
- 正規表現的クエリ言語 と DFAエンジン により、圧倒的なパフォーマンスを実現
- jq 等の変換・加工ツールとは用途が異なるため、使い分けが重要
参考リンク
- crates.io: jsongrep
- ripgrep: Andrew Gallantのブログ記事
- Rust公式: serde_json_borrow