| 日本語全文検索エンジン"Freya" |
|---|
| Full-text Retrieval Engine for Your Archives |
索引は findex(1)を使って作成します。しかし,findexが入力として受け付けるのはFDIFファイルのみです。各種の文書ファイルをこのFDIFファイルに統一してから,findexを起動することになります。FDIFファイルはXML文書のようなものです(*1)。
(*1) FDIFは一見するとXMLの適性形式に準拠しているように見えます。が,findexは任意のXML文書を受け付けるわけではありません。また,FDIF形式はXMLに適合していない部分もあります(Unicodeを採用していないなど)。さらに現在のfindex(1)の実装は実験的なものであり,タグはすべて行頭から始まる必要があるなど(^_^;,極めて制限の大きいものとなっています。そのため,今後,FDIF形式を別のフォーマットに変更する可能性があります。わざわざ,XML風にしているのは今後を考えてのことではあるのですが。
html2fdifはlibwww-perl-5を使用するので,あらかじめインストールしておい てください。html2fdif はファイル名とそのファイルに対応するURLを並べたリストを受けとり,それらのファイルをFDIF形式に変換して出力します。また,同時に.dscファイルも作成します。まず,各行にファイル名(html2fdifを実行するディレクトリからの相対パスあるいは絶対パス)と検索結果の表示に使用するURLをスペース句切りで並べたファイルを用意します。
% cd /usr/local/etc/httpd % mkdir freya % find htdocs -name '*.html' -print | sed -e 's/\(.*\)/\1 \1/;s/ htdocs/ http:\/\ www.graco.c.u-tokyo.ac.jp/' > freya/web.list
このリストを -f オプションで指定することで,変換が実行されます。-o オプションには生成するファイルの名前を指定します。たとえば,-o hoge とした場合,hoge.dsc と hoge.fdif が出力されます。省略すると -o default が仮定されます。
% html2fdif -v -o freya/web -f freya/web.list
FDIF形式のテキストが出力されたら,それをfindex(1)で処理することで索引を作ることができます。
findexでも -o オプションで出力する索引の名前を指定します。-o hoge とすると,hoge.lex, hoge.idx, hoge.map を出力します。省略すると "default" が指定されたものとみなされます。デフォルトの形態素辞書以外を使うときは -d オプションで指定します。
% cd freya % findex -d /usr/local/lib/freya/dict/icot.dic -o web web.fdif
索引作成時にはテンポラリファイルが作られます。索引名の末尾に '_' がついたファイルがそうです。これらのファイルは実行時に消さないように注意してください。
mail2fdif はファイル名を並べたリストを受けとり,それらのファイルをFDIF形式に変換して出力します。また,同時に.dscファイルも作成します。処理対象のメールは,1メールにつき1ファイルになっている必要があります。また,ヘッダ部分と本体部分が空行で句切られていなくてはなりません。
% mkdir ~/Indices % cd ~/Mail % find hoge-ml -type f -print > ~/Indices/hoge.list % mail2fdif -v -o ~/Indices/hoge -f ~/Indices/hoge.list % cd ~/Indices % findex -d /usr/local/lib/freya/dict/icot.dic -o hoge hoge.fdif
mail2fdif で作成した索引を fsearch.cgi で使うことも可能です。ただし,WWW上で使う以上,一通一通のメールに適切なURLが存在する必要があります。次のような手順で作業を行なえばよいでしょう。メールから変換して作成されたHTMLファイルを,html2fdifで処理しても検索可能にはなりますが,要約等が見苦しくなりがちです。それに,mail2fdifを使えば,author:harada などの条件での検索が可能になります。
メール -------------------> HTML ==> WWW上に公開 | 1.hypermail/MHonArc / | / |2.mail2fdif <------ URL v FDIF --------------------> 索引 ==> 4. fsearch.cgi?style=mail
Freyaを使うことで作成されるファイルは以下のようになります。一セットの索引につき,4つのファイルがfsearch(1), fsearch.cgi(1)によって使用されることになります。
| 拡張子 | 概要 | 検索時に必要? | 作成するプログラム |
| hoge.fdif | FDIF形式テキスト | 不要 | html2fdifなど |
| hoge.dsc | 検索結果表示用要約ファイル | 要 | html2fdifなど |
| hoge.lex | 索引ファイル(見出し語) | 要 | findex/fmerge |
| hoge.idx | 索引ファイル(本体) | 要 | findex/fmerge |
| hoge.map | 出現位置座標変換用ファイル | 要 | findex/fmerge |
| icot.dic | 形態素辞書 | 不要 | mkicotdic,fmkmorphdic |
これらをすべてを合わせると(文書の内容によって変動しますが),元のテキストの70%くらいの容量を占めることになります。ある程度のオーバーヘッドがあるため,大量のファイルを処理するほど,格納効率はよくなります。
fmerge(1)で複数の索引ファイルをマージし,一つにまとめることができます。マージの対象となるのは,検索時と同様で,.dsc, .map, .lex, .idx の4つのファイルです。たとえば,base.{dsc,map,lex,idx}, news.{dsc,map,lex,idx},local.{dsc,map,lex,idx} という3セット(12ファイル)の索引があるときにこれらをまとめて all.{dsc,map,lex,idx} という索引を作るには,次のようにします。
% fmerge all base news local
大量の文書(だいたい1万ファイル以上)を処理する場合は,数千ファイルずつfindexで索引づけし,最後にfmergeでマージするようにしたほうが確実でしょう。findexも内部的には小さな索引ファイルを作り,最後にマージを行なうように出来ています。HTMLから作った索引とメールから作った索引を混ぜることも不可能ではありません。しかし,検索結果を表示する際はいずれか一種類(またはgeneric表示)を選ばなくてはなりませんので,あまり意味がないでしょう。
fsearch(1)を使うことでコマンドラインから検索できます。検索時にはhoge.dsc, hoge.map, hoge.idx, hoge.lex という4種類の索引ファイルが必要です。
Usage: fsearch [-s mail|html] [-f n] [-t n] -i index key [key ..]
fsearchのオプションは以下の通りです。
まず,CGI用ディレクトリを用意してください。cgi-binを直接使うのではなく,専用のディレクトリを作ったほうがよいでしょう。たとえば,cgi-bin/fsearch/などを作ります。そこにmakeした cgi-bin/fsearch.cgi とパッケージに含まれている cgi-bin/head.html, cgi-bin/foot.html,cgi-bin/error.htmlをコピーします。
% cd /usr/local/etc/httpd
% mkdir cgi-bin/fsearch
% cp /usr/local/lib/freya/cgi-bin/fsearch.cgi cgi-bin/fsearch
% cp /usr/local/lib/freya/cgi-bin/{head,foot,error}.html cgi-bin/fsearch
また,検索時に必要な索引ファイルを同じディレクトリコピーします。
% cp freya/web.{dsc,map,idx,lex} cgi-bin/fsearch
CGIを使うためのインターフェースとして,<FORM>タグを含んだHTMLを用意します。サンプルが cgi-bin/fsearch.html に用意されていますので,これを/usr/local/etc/httpd/htdocs/fsearch.html にコピーし,編集します。
% cp /usr/local/lib/freya/cgi-bin/fsearch.html htdocs
もちろんfsearch.html以外のファイル名にしても構いませんし,既存のHTMLに<FORM>を加えてもよいでしょう。
<FORM METHOD="GET" ACTION="/cgi-bin/fsearch/fsearch.cgi"><NOBR> <B><A NAME="form">検索式</A></B>: <INPUT TYPE="text" NAME="key" VALUE="" SIZE=35> <INPUT TYPE="hidden" NAME="from" VALUE="0"> <INPUT TYPE="hidden" NAME="n" VALUE="20"> <INPUT TYPE="hidden" NAME="index" VALUE="web"> <INPUT TYPE="submit" NAME="go" VALUE="Search"> </NOBR></FORM>
パラメータ from, n, index は次のような意味になります。
index等を適切に指定したら,fsearch.html をWWWブラウザで閲覧し,検索を実行してみます。うまく動いたでしょうか? 動かない場合は httpd のエラーログを見るなどして,対応してみてください。
注: fsearch.cgi以外のファイル(索引ファイルやfoot.html)にアクセスした場合にエラーになることを確かめてください。必要ないファイルが外部から見えてしまうとセキュリティホールになりかねません。
fsearch.cgi は実行時のカレントディレクトリ(fsearch.cgiのあるディレクトリ)に fsearch.log というファイル名のログを書き込みます。動作確認の際にfsearch.logができていることも確かめてください。出来ていないとすると,おそらくはパーミッションに問題があるのでしょう。fsearch.logはCGIを実行するユーザーが作成できる・書き込める必要があります。CGIを実行するユーザーはWWWサーバーの設定にもよりますが,nobodyになっているのが普通です。
さて,CGIを置くディレクトリごと誰でも書き込めるようにしてもよいのですが,それはセキュリティの観点からはあまり好ましくありません。そこでここでは空の fsearch.log を作り,そのファイルだけ誰でも書き込めるようにします。
% cd cgi-bin/fsearch % touch fsearch.log % chmod a+w fsearch.log % chmod go-r fsearch.log
あるいは特権ユーザーになって,所有者が nobody のファイルにしてもよいでしょう。
% su # cd cgi-bin/fsearch # touch fsearch.log # chown nobody fsearch.log
ログの各行は次のような情報が記録されます。
残りの部分には検索式が日本語EUCで記録されます。入力された内容そのままではなく,全角半角等の正規化が行なわれてから記録されます。検索式が入力されなかった場合は "-" が記録されます。
例:08 Jan 1998 05:44:09 JST ppp123.yonde.ne.jp - default html 34 1 20 foo bar
fsearch.cgiによる検索が正しく動作したら,検索結果表示画面のカスタマイズを行ないます。さきほど cgi-bin/fsearch/ にコピーした,head.html,foot.html, error.htmlを編集してデザイン等を好みに合わせて変更してください。メールアドレスをWWWサーバー管理者のアドレスにするなどしてください(your@mail.host.domになっている部分)。
各HTMLには以下の変数(キーワード)を書くことができます。
これらの使用例は実際に cgi-bin/{head.html,foot.html,error.html}を見てください。複数の索引ファイルがあるときに選択して検索したい場合は,たとえば以下のようにすればよいでしょう。
< FORM METHOD="GET" ACTION="/cgi-bin/fsearch/fsearch.cgi"> < NOBR> < B> < A NAME="form"> 検索式< /A> < /B> : < SELECT NAME="index"> < OPTION VALUE="all"> 全体(local以外)から検索< /OPTION> < OPTION VALUE="personal"> 個人ページのみ検索< /OPTION> < OPTION VALUE="fresh"> 最近更新されたページのみ検索< /OPTION> < /SELECT> < INPUT TYPE="text" NAME="key" VALUE="" SIZE=35> < INPUT TYPE="hidden" NAME="from" VALUE="0"> < INPUT TYPE="hidden" NAME="n" VALUE="20"> < INPUT TYPE="submit" NAME="go" VALUE="Search"> < /NOBR> < /FORM>
fsearch.cgiの出力は日本語EUCになっていますが,次のようなwrapperを用意することで,ISO-2022-JPを出力させることも可能です。
#!/bin/sh ./fsearch.cgi | exec /usr/local/bin/nkf -j
これを例えばfsearchj.cgi というファイル名でfsearch.cgiと同じディレクトリに置き,fsearch.cgiのかわりに使えばよいでしょう。もちろん,/usr/local/bin/nkf の部分は適当に書き換えてください。単にexec nkf -j と書くと,nkf がCGIで許されるパスに存在する場合にしかうまく動かないので注意が必要です。