隔週連載groonga

第4回 rroongaを使ったソースコード検索エンジンMilkode

この記事を読むのに必要な時間:およそ 4 分

Milkodeでの使い方

Milkodeでは,主に2つのテーブルを使っています。

  1. ソースコードのテーブル(documents)
  2. パッケージのテーブル(packages)※5

特に重要なのはdocumentsテーブルです。検索対象となるすべてのファイルが1つのテーブルに格納されています。

  • 1ファイル == 1レコード として登録している
  • パッケージごとにテーブルを分けたりはしない
    • 全文検索のクエリとしてpackageカラムを指定した方が高速なため
  • 拡張子はソースコードにとって大切な情報なので専用カラムを作成
    • .cと.cppを区別することができる
※5
Milkodeにおける追加単位,ひとつのソースツリー(例えばmilkode,rroonga-2.0.6)に相当します。

documentsテーブルのスキーマ

それではdocumentsテーブルのスキーマ情報をみてましょう。

カラム名説明実例全文検索
pathstringファイルの絶対パス/path/to/proj/src/aaa.txt
packagestringパッケージ名proj
restpathstringパッケージ名以降のパスsrc/aaa.txt
contenttextファイルの内容aaa\nbbb\nccc
timestamptimeファイルのタイムスタンプ2012-11-21 23:26:00 +0900-
suffixtext拡張子txt

定義するためのRubyコード

実際にスキーマを定義しているのは/milkode/lib/milkode/database/document_table.rbの11行目です。

module Milkode
  class DocumentTable
    def self.define_schema
      Groonga::Schema.define do |schema|
        schema.create_table("documents", :type => :hash) do |table|
          table.string("path")
          table.string("package")
          table.string("restpath")
          table.text("content")
          table.time("timestamp")
          table.text("suffix")
        end

        schema.create_table("terms",
                            :type => :patricia_trie,
                            :key_normalize => true,
                            :default_tokenizer => "TokenBigramSplitSymbolAlphaDigit") do |table|
          table.index("documents.path")
          table.index("documents.package")
          table.index("documents.restpath")
          table.index("documents.content")
          table.index("documents.suffix")
        end
      end
    end

さらに詳しい使い方を知りたい人は,milkode/database/document_table.rb辺りから読んでみてください。

とりあえず完成 「行指向のソースコード検索エンジンMilkode」

こうしてrroongaのおかげでMilkodeができました。ブラウザで検索すると次のような画面になります。

Milkodeのホーム画面

Milkodeのホーム画面

他の検索ツールと比較した時の特徴として,次のような点が挙げられます。

  • インデックス型のため,数万オーダーのファイルが登録されていても1秒以内に検索できる※6
  • しかし,grep型のように複数のキーワードを含むを見つけることができる
  • ブラウザからもコマンドラインからも検索することができる
  • 個人用のデスクトップアプリケーションとしても使えるし,デプロイして共有のWebアプリにすることもできる

Milkodeのインストールはgemから行います。

$ gem install milkode

それにより,次のコマンドが使えるようになります。

コマンド概要
milkgitライクなコマンドを使って検索したいディレクトリを登録
milk webWebアプリを立ち上げてブラウザから検索
gmilkgrepのようにコマンドラインから検索
mcd登録したディレクトリ間を素早く移動

さらに詳しい使い方はhttp://milkode.ongaeshi.meをご覧ください。

派生物として,自分のGitHubレポジトリのソースコードをオフラインで高速に検索できるMyGitHubというのもあります。

※6
私がローカルで使っているものはすでに15万ファイルほど登録されていますが軽快に動作しています。

まとめ

rroongaを使って良かった点はやはり検索の高速性です。勉強会などで人に見せる機会があるとほとんどの人が検索結果が返ってくるまでのスピードに驚いてくれます。grep型のものと比べると驚く程速いです。また,Rubyらしい書き方で全文検索エンジンにアクセスできるのもとてもよいところです。

困った点として,Windowsなどの一部環境で安定して動いていなかった(Milkodeの症状で言うと20,000レコード程度登録するとSEGV)というのがあったのですが,groongaチームの皆さんがバグ報告から原因を見つけてくれ昨年11月にリリースされたrroonga2.0.9で無事直りました。手元のWindowsではすでに安定して動作しています※7)⁠

全文検索というとWebアプリのものというイメージがありますが,rroongaはgemさえインストールすればRubyから簡単に使うことができるため,ちょっとしたツールにも使うことができます。ファイルやデータを一つずつ検索すると遅いからもっと早く検索したいなあ,といった要求があったときは是非rroonga(とその内部のgroonga)を使ってみてください!

※7
データベースには12万ファイルほど登録されていました。

次回予告

次回はgroongaをライブラリとして使っているプロダクトの紹介です。今回でてきたrroongaについて詳しく紹介します。rroongaが大事にしていることはいったいなんでしょう。お楽しみに!

groongaの利用事例を寄稿しませんか

連載の目的は「読者の皆さんがgroongaを使いたくなる!」ことです。そこで,すでにgroongaを使っており,groongaの利用事例を本連載で紹介していただける人を募集します。募集要項を参考にご連絡ください。お待ちしています!

著者プロフィール

おんがえし(ongaeshi)

プログラマ。職業プログラマの傍らでオープンソースのソフトウェアを作る。最近作ったのはMilkodeFireLinkauto-shell-command.elなど。こつこつと何かを作りながら生きていければよいと思っている。

Twitte:@ongaeshi
ホームページhttp://ongaeshi.me