コード検索の難しさ
- Val Townの現在の検索機能はPostgresのILIKE機能に基づいており、検索語がコード内にあれば検索結果に含まれる単純な部分文字列検索しかサポートしていない
- 検索結果のランキングはほとんどなく、複数単語を含む検索もうまくサポートされていない
- より良い検索機能は、最も多く要望されている機能の1つである
自然言語検索とコード検索の違い
- 一般的な検索ソリューションは英語などの自然言語を対象としているため、コード検索には適していない
- Stop wordsの除去、Stemming、Lemmatizationなどのアルゴリズムは、コードではむしろ問題を引き起こす
- たとえば
the はTypeScriptではstop-wordではなく、検索したい有効な変数名である可能性がある
- 単語境界も異なり、関数名をstemmingしても大きな意味はない
PostgresのFull Text Search
- PostgresのFull Text Search拡張は、ある程度の規模まではうまく動作するが、大規模になると性能上の問題に突き当たる
- 小さなチームではインフラを可能な限りシンプルに保つことが重要なため、Postgresですべてを解決しようとするが、現在はシングルノードPostgresクラスタの限界に挑戦しているところである
- FTSを使ったコード検索の事例を見つけるのは難しい
pg_trgrmを使ったTrigram検索
- Trigram検索は、コード検索で成功した事例がある
- Google Code Search、GitHubの新しい検索システム、Sourcegraph など
- Postgresの
pg_trgrm 拡張を使って検索テキストカラムにGINインデックスを作成し、Trigram検索をサポートする
- 正規表現検索には良い解決策だが、自由な検索語に対しては適切なランキングを作るのが難しい
コード検索のためのさまざまな選択肢
- Meilisearch、Typesense、Zoekt、ParadeDB、Sonic などさまざまな検索エンジンがあるが、その多くはコード検索に特化していない
- GitHubやSourcegraphなどのコード検索は優れているが、専任チームと多くの時間投資の成果物である
- Elasticsearchは多くのカスタマイズができるが、小さなチームには運用負担が大きい
- MeilisearchはRustで作られたESの代替だが、よりレイテンシに重点を置いているように見える
- ParadeDBは「ただのPostgres」を掲げ、ESに似た機能を約束しているが、まだ使えない
GN⁺の意見
- 現在Val Townで使っているように、初期段階ではPostgresの基本機能だけでコード検索を実装するのは、インフラ運用の負担を減らせる賢明な選択に見える。しかし、サービス規模が大きくなれば、専用検索エンジンの導入は避けられないように思える
- 規模が大きくなれば、Elasticsearch程度の導入は必要になりそうだが、この場合でもクラウドのマネージドサービスを使うことが、インフラ運用負担を減らす方法になるだろう
- コード検索に特化したオープンソースが多くない点は残念である。コード検索の重要性がますます高まっているだけに、今後はSourcegraphのようなコード検索特化型のオープンソースプロジェクトがより活発になるとよい
- 単純な文字列検索を超えて、コードの構造的な特性を反映した検索ランキングアルゴリズムに関する研究が必要に見える。たとえば変数名、関数名、コメントなどを区別して重みを変える方式など
- 長期的には、Large Language Modelを活用したSemantic Code Searchの方向へ発展していくと予想される。同じロジックでも命名やフォーマットが異なるコードを見つけられるセマンティック検索が可能になれば、開発生産性に大きく役立つだろう
1件のコメント
Hacker Newsのコメント
Sourcegraph は大規模なコード検索を扱っているが、立ち上げ当初はインデックスなしのリアルタイム検索だけでも、思ったより長くうまく機能する。最初の N 件の一致だけ見つければよいからだ。こういうものを作っている人たちとの会話は歓迎。
優れたコード検索プラットフォームは生活をずっと楽にしてくれる。Google を離れたら、社内コード検索機能がいちばん恋しくなるだろう。他のあらゆるものとうまく統合されていて、ない状態は想像できない。GitHub 検索を使うたびに、なおさらそのありがたみを感じる。悪くはないが、汎用的なコード検索プラットフォームを構築するのは本質的にはるかに難しい。
新しい開発者に明示的に教えることはあまりないが、初期に身につけるべき絶対に重要な基礎コード検索スキルについての理解の進み方:
Ctrl+Fの使い方を学ぶripgrepに移行するripgrepからgrepに移って、いくつかのフラグを学ぶripgrepでできることには限界があると気づき、実際にインデックス化された専用のコード検索ツールに移行するIDE や開発ツールの作者たちは、コード検索をきちんと実現するにはコンパイラプラットフォームを開放しなければならない、という洞察をずっと前から持っていた。優れたコード検索は、リファクタリング支援、自動補完、その他の一般的な IDE 機能の基盤になる。
IBM は Eclipse でこれを実現したが、それ以降はそれに匹敵するものがなかった。Eclipse には、構文エラーがある場合でも使える Java 向けの高速な増分コンパイラがあり、IDE のコード表現はそのコンパイラと結び付いていた。
最近見た中で最も興味深いコード検索アプローチの 1 つは
septumで、周辺コンテキストを適切な量だけファイル単位で取得することを目指している。もう 1 つはstack-graphsで、コードベース全体にわたるシンボリックな関係を増分的に解決しようとしている。オープンソースソリューションの有力候補だと思っていた
houndが言及されていないのは意外だった。GitHub が妙なトークン化の挙動を「修正」して、いら立たされたことがある。IDE スタイルの find-usages 機能を改善しているものの、まだ完璧ではないので、
foo.bar()のテキスト検索をしたい場面があるのに、このステミング挙動のせいで foo と bar が言及されたすべての場所が見つかってしまい、結果が水増しされる。彼らが Zoekt に対して及び腰なのが理解できない。他の選択肢より「新しいインフラの約束」だとは思えない。サーバーとインデクサーは単一バイナリなので、これ以上シンプルにはなりようがない。Elasticsearch より怖がる理由もなさそうだ。
Oracle には、ロードされたすべての PL/SQL コードが提示される USER/ALL/DBA_SOURCE ビューがある。EnterpriseDB がこれを Postgres 内部に実装しているのか、それとも拡張として利用できるのか気になる。
GitHub 検索が素晴らしいって? ほとんどの場合ほぼ役に立たないように感じるし、clone + ripgrep のほうがずっと効率的だと思う。問題は検索そのものというより、UX がひどいことにある気がする。