Redmineで日本語でリポジトリを検索できるかもしれない


Redmineでリポジトリ検索する機能を提供するプラグインは自分が知る限りでは 2個 あります。

1. redmine_reposearchプラグイン

説明: "Hyper Estraier"という検索エンジンを使ってリポジトリを全文検索します。しかし残念ながらプラグインの更新が止まっていて Redmine 3.xに対応していません。プラグインのRedmine 3.x対応に期待します。

2. redmine_xapianプラグイン

説明: Xapianという検索エンジンを使ってリポジトリを全文検索します。ファイル管理のプラグインであるredmine_dmsfプラグインにもXapianが使用されてます。Redmineの最新バージョンにもちゃんと対応してます。しかし残念ながら日本語に対応していません。プラグインがサポートする言語の一覧の中に日本語がありません。

上記のとおり、最新のRedmineに対応した、日本語でリポジトリを検索できるプラグインは、一見無いです。

ああ、残念と思っていた所ですが………もしかするとredmine_xapianプラグインでは日本語検索ができるのでは?!と思う材料を得ました。

「(検索エンジンの)Xapianがサポートする言語」のサポート内容ですが、公式ページの機能紹介には"Supports stemming of search terms (e.g. a search for "football" would match documents which mention "footballs" or "footballer"). "という説明があります。この「語幹検索(stemming of search terms)」とは"football"という単語を検索すると、語幹を拾って、"footballs"や"footballer"もヒットするものです。この検索手法のサポート対象に日本語は含まれません。

しかしそれとは別に、XapianはCJK(中国語、日本語、韓国語)向けのサポートとして、単語単位ではなく文字単位で検索する手法(N-Gram)で検索用インデックスを作れます。(Xapian-1.2.8から)
「N-Gramって何??」ですが、英語等は単語がスペースやカンマで区切られます。これを「わかち書き」というそうです。これに対し、CJKでは文字列に単語間の区切り文字がありません。そのため、単語単位ではなく文字単位の検索が必要で、それに対応した検索手法が N-Gram だそうです。

「Redmineで日本語でリポジトリを検索する」に話を戻すと、redmine_xapianプラグインは、語幹検索は日本語に対応していないものの、N-Gramには対応しているので、日本語でリポジトリを検索ができるのではないか という予測ができます。

手段は、1. まずはXapianのバージョンを1.2.8以上にする 2. 検索用インデックス作成時に環境変数にXAPIAN_CJK_NGRAM=1を設定("export XAPIAN_CJK_NGRAM=1")してインデックスを作成する。の2点です。

近日中に、redmine_xapianプラグインにより(N-Gramで検索用インデックスを作れば)日本語でリポジトリを検索できるか、確認したいと思います。

【追記】
「Redmine3.3+Xapian1.2.8-1」で、環境変数を何も変更しなくても、 Redmine_Xapianプラグインにより全角スペースに囲まれた日本語の単語の検索がある程度できる事を確認しました。 しかし、以下のように不便な点がいくつかありました。

  • プラグインが対応するエンコードがUTF-8のみのため、Shift-JISの日本語は対象外。(事前にutf-8変換を入れられれば何とかなるかも)
  • Word(.docx)、Excel(.xlsx)ファイルはunzipでXMLに変換した内容をテキストとして読むため、xmlのタグが混ざって検索できない場合がある。
    例) Word本文の「あいうえお」がXML化により「あいう<タグ>えお」のようにタグが混じると、「あいうえお」では検索にヒットしない
  • PDF, word(.doc)のファイルの文字列が日本語だけでなく英語も検索できない。(プラグインの不具合?) → プラグイン開発者に不具合を報告したところ、数日後に修正して下さりました。(早い!)正式にはv1.6.8のリリースで修正が入ります。 https://github.com/xelkano/redmine_xapian/issues/88
  • (リポジトリ検索でなく添付ファイル検索のケースで) Internal 500エラーが発生する場合がある。(常にではなくファイルの文字列中にutf-8に変換できない文字コードがある場合のみ)