Last Modified: 2000-01-26
このファイルは主にプログラムの使い方をまとめたマニュアルです。 ソフトウェアの概要に関するドキュメントは intro.html の方を参照してください。本 プログラムは GPL2 に従ったフリーソフト ウェアです。完全に無保証ですので運用は個人の責任で行って下さ い。
http://openlab.ring.gr.jp/namazu/ に Namazu のペイジがあります。
v1.3.0.11 では CGIに関するセキュリティーホール (/tmpなどにゴ ミのファイルを作られてしまう) を修正しました。古いヴァージョ ンを利用している方は必ずヴァージョンを上げてください。
v1.3.0.10 では mknmz のロックに関するバグを修正しました。
v1.3.0.8 では namazu.conf, .namazurc で REPLACE を複数、設定 できるようにしました (武藤武士さん Thanks)。その他、細かいバ グをいくつか修正しています。
v1.3.0.7 では細かいバグをたくさん修正しています。
v1.3.0.6 では RFCのインデックスが異常に遅かったバグを修正し ました。そのほかいくつかの細かいバグを修正しています。詳しく は ChangeLog を参照してください。
v1.3.0.5 では ChaSen を使ったときに発生するキーワードの重みづけの バグを直しました。日本語のわかち書きに ChaSen を使っている方はぜひ v1.3.0.5 にヴァージョンを上げてください。
v1.3.0.4 では、 NMZ.log の Total Files: の値が変だったバグを修正し ました。この変更によって v1.3.0.4 より前のヴァージョンで作ったイン デックスを更新すると NMZ.head.{ja,en} の「現在 xxx のファイルがイ ンデックス化され」の数値がおかしくなるかもしれません。その場合は添 付の gtnmz を
% gtnmz NMZ.r
と実行して得られる数値をNMZ.total に同じ値を書き込み、 NMZ.head.{en,ja} の該当位置に埋め込んでください。
v1.3.0.0 では文書の更新/削除に対応したイン デックスのアップデートができるようになりました。ウェブペイジな どを対象とする場合に便利です。ゴミ掃除機の gcnmz (古川@ヤマハさ ん作)もあります。
v1.3.0.0 では文書の日付による検索結果の新しい順/古い順のソートができるようになりました。
v1.3.0.0 ではフィールド指定の検索 ができるようになりました。 Mail/News を検索する際に便利です。 この機能は v1.3.0.0 で作ったインデックスでなければ使えません (NMZ.field.{subject,from,message-id} といったファイルが必要)。
従来のインデックスも扱うことはできますが、 v1.3.0.0 の新機能を発揮 するためにもインデックスを作り直すことをお勧めします。
その他の変更点については ChangeLog を参照してください。
日本語を扱うために KAKASI または ChaSen を必要とします。 KAKASI を用いる場合は、京都大学の馬場肇さんが作成された「わかち書きパッチ」をあてた KAKASI でなければなりません。 FreeBSD の ports に収録されている KAKASI は FreeBSD 2.2.5-RELEASE から「わかち書きパッチ」が当たっているようです。 このパッチは元々 freeWAIS-sf を日本語化するために作成されたもので、馬場さんの freeWAIS-sf japanization information から情報が手に入ります。
このパッチは 1997-09-02 付けで更新され、 kakasi -Ea -w と実行したときの小さなバグが取れました。 Namazu ではこのバグを吸収するルーチンをいれてありますが、 KAKASI 自身を新しくしたほうが良いでしょう。
KAKASIは KAKASI から 入手可能です。
ChaSen は奈良先端科学技術大学院大学で開発された日本語の形態素解析を行うソフトウェアです。 単純にわかち書き出力をさせる分には KAKASI と比べて品質にそれほど差はないようですが、品詞情報の抽出を行えるためきめの細かい日本語処理を行うことができます。 ChaSen を使用するには必要なファイルを http://cactus.aist-nara.ac.jp/lab/nlt/chasen.html から取得してドキュメントに従って make してください。
両者を比べると、処理速度は KAKASI の方が高速です。 また、展開後の辞書のサイズは ChaSen が 約 7 MB, KAKASI が約 2 MB になります。 ディフォルトでは KAKASI を用いるものとして設定してあるため、 ChaSen を用いるにはいくつかの注意が必要です。 ドキュメントをよく読むようにしてください。 ChaSen による品詞情報を利用した処理を行う効果については ChaSen による品詞情報の利用を参照してください。 現在はまだ実験段階です。
日本語のインデックス処理の品質は用いる辞書に依存します。 KAKASI の標準の辞書は 10 万語以上の単語が登録されているので、ごく標準的な文章ならば特に不満もなく使えると思われますが、人名、地名、専門用語などについてはどうしても弱くなります。 この欠点を補うために KAKASI では辞書の強化が比較的容易に行えるようになっており、フリーの専門用語辞書なども出回っているようですから、それらを用いることをお勧めします。 この辺りの問題点については馬場さんの freeWAIS-sf japanization information の日本語化パッチの問題点の章に詳しいです。
中には条件によって使用制限があるものもあるかもしれません。 よくドキュメントを読んでから使用した方が良いでしょう。
過去に一度でも Namazu の動いたことのある環境です。 もしかしたら Namazu の新しい版では動かないかもしれません。
Win32 で make するのは結構大変です。わざわざ make しなくても Win32 用のバイナリパッケージ を使えば比較的容易に動かすことができます。 その場合についてはWin32 用のバイナリパッケージを用いるの項を参照してください。
ソースから自分で make するにはまず、
といったソフトウェアを集めてきてインストールする必要があります。 Perl for Win32 は CPAN の ports/win32/ActiveWare/Release/Pw32i315.exe で動作確認しました。 さらにこれらとは別に日本語 EUC, JIS コード対応のエディタ (Mule for Win32 や秀丸) もあった方が良いでしょう。 Web Server としては Apache-1.3b3-win32, OMNI HTTPD, fnord 1.0.0.23, ANhttpd あたりが使えるようです。
OS/2 への移植は清水@住友林業さんが行ってくれました。動作には
が必要になります。 Makefile は専用の Makefile.OS2 が用意されていますのでこちらをご利用下さい。 OS/2 での動作については清水さんのウェブペイジ に情報があります。
まずはアーカイヴを展開します。GNU 版の tar なら
tar xzvf
namazu-xxx.tar.gz
そうでなければ
gunzip -c
namazu-xxx.tar.gz| tar xvf -
zcat
namazu-xxx.tar.gz | tar xvf -
のようにしてファイルを展開してます。
v1.2.0 からは configure が添付されました。まず最初に
./configure
のように実行して Makefile を作成します。 Perl, KAKASI/ChaSen, nkf のパスは自動検出します。
通常は configure の作成した Makefile がそのまま使えますから何も修正しないで make を実行して構いません。編集したい場合は次の項を参照してください。もっとも単純な Namazu のインストール方法は以下の通りです。
./configure
make
(必要に応じて root になって)
make install
大抵はこれでうまくいくと思います。何か問題が発生した場合はお使いの 環境やエラーメッセージなどの詳しいレポートを私の方まで送ってもらえ れば対応できるかもしれません。
v1.1.0 からは Makefile を編集してインストールします (原型は佐藤文優@cij.co.jp さんが作ってくださいました Thanks!)。必要に応じて
BASEDIR = /usr/local
CGIDIR = $(BASEDIR)/etc/httpd/cgi-bin
NAMAZUDIR = $(BASEDIR)/namazu
BINDIR_SYS = $(BASEDIR)/bin
BINDIR = $(NAMAZUDIR)/bin
INDEXDIR = $(NAMAZUDIR)/index
DOCDIR = $(NAMAZUDIR)/doc
LIBDIR = $(NAMAZUDIR)/lib
OPT_NAMAZU_CONF = $LIBDIR/namazu.conf
OPT_URL_CGIBIN = /cgi-bin
OPT_ADMIN_EMAIL = webmaster@foo.bar.jp
OPT_PATH_PERL = /usr/bin/perl
OPT_PATH_NKF = /usr/local/bin/nkf
OPT_PATH_KAKASI = /usr/local/bin/kakasi
OPT_PATH_CHASEN = /usr/local/bin/chasen
WAKATI = KAKASI
LANG = ja
あたりを自分のサイトに合わせて変更します。それぞれ
CGIDIR = $(BASEDIR)/etc/httpd/cgi-bin
NAMAZUDIR = $(BASEDIR)/namazu
BINDIR_SYS = $(BASEDIR)/bin
BINDIR = $(NAMAZUDIR)/bin
INDEXDIR = $(NAMAZUDIR)/index
DOCDIR = $(NAMAZUDIR)/doc
LIBDIR = $(NAMAZUDIR)/lib
CONTRIBDIR = $(NAMAZUDIR)/contrib
OPT_NAMAZU_CONF = $(LIBDIR)/namazu.conf
URL_CGIBIN = /cgi-bin
OPT_ADMIN_EMAIL = foobar@foo.bar.jp
OPT_PATH_*
WAKATI = KAKASI
LANG = ja
となっています。 Makefile 自体にコメントをいれているのでそちらも参照してください。 Makefile で指定できない細かい設定をする場合は直接ソースを修正することになります。
make には sed が必要です。また、 Win32 の場合は \bin に GNU-Win32 の sh.exe を置いておく必要があります。 Namazu の make は基本的には
make clean
make
make install
の手順になります。 make が成功するとそれぞれ mknmz, wdnmz, namazu* が作成されます。 make install でインストールされます。 CGIは make install_cgi でインストールします。
Namazu のWin32用のパッケージを広瀬@NECエンジニアリングさんが用意してくださいました。 また、全文検索システム Namazu for Win32のホームペイジも作って頂きました。 Win32版に関する詳しい情報はそちらを参照してください。
Namazu の Win32 用バイナリパッケージに含まれる namazu.exe および kakasi.exe は GNU-Win32 の gcc で make されています。実行には cygwin.dll が必要ですので、注意してください。 mknmz の方は
perl mknmz
のように perl に実行させます。基本的にこのマニュアルの内容は UNIX用に書かれていますが、Win32 でもほぼ同じような使い方がで きると思います。ただ、プログラムの性質からして初心者向けでは ないでしょうから、ある程度の知識がある方じゃないと難しいかも 知れません。
NMZ.head.ja, NMZ.foot.ja を編集するために JIS コード対応のエディ タ (Mule for Win32 や秀丸) が必要になります。これらも用意しておい てください。
インデックスを作成するには mknmz の引数にインデックスを作成する元となるファイルのあるディレクトリ名を与えます。 つまり /home/foo/public_html を対象とするならば
% mknmz
/home/foo/public_html
と実行すれば /home/foo/public_html 以下の *.html *.txt といったファイル (Makefile の OPT_TARGET_FILE に定義されています) をすべてインデックスして、 mknmz を実行したカレントディレクトリに NMZ.* というファイルを作成します。 mknmz にはいくつかのオプション があります。それらについては mknmz のコマンド ラインオプション の項で述べます。
二度目以降は、前回以降に追加/更新/削除されたファイルを抽出してイン デックスをアップデートする仕組みになっています。文書の更新/削除の 検出を抑制するには -Z オプションをつけてください。削除された文書の 検出のみを抑制するときは -Y オプション用います。
make で作成された namazu
が検索プログラムです。
% namazu
/home/quux/namazu/index"
bar"
のように実行すれば、 /home/quux/namazu/index
(これは Makefile の INDEXDIR
で設定したディレクトリの場合は省略できます)
にある NMZ.* をもとにキーワード bar を検索します。 namazu
のコマンドラインオプションは別の項で説明します。
ディフォルトではコマンドラインから実行した際はプレインなテキストで出力します。
HTML で出力したい場合には -h オプションを指定します。
また、
% namazu
/home/quux/namazu/index/hoge1 /home/quux/namazu/index/hoge2
"
bar"
のように複数のインデックス (hoge1, hoge2) を指定することもできます。
CGI として動作させる場合は検索対象となるインデックスファイルを Makefie の
INDEXDIR
で指定したディレクトリ、
または namazu.conf ファイルで設定した場所にに置く必要があります。
そうでないと CGI プログラムから参照できないので注意してください。
ディフォルトでは mknmz によって作成されるインデックスには
<A HREF="/home/quux/public_html/index.html">
のように URL が展開されています。
ローカルのディスクを対象としたときはこれで良いと思いますが、 WWW 用の検索エンジンを作るときは困ります。
CGI として用いるために
http://
から始まる URL を作成するにはいくつかの方法があります。
一つは
REPLACE /home/foo/public_html/ http://foo.bar.jp/%7Efoo/
のように指定しておくことで (各項目は TAB で区切ってください)、
検索結果の出力時に /home/foo/public_html/
の部
分を http://foo.bar.jp/%7Efoo/
に動的に置き換え
て出力できます。この方法ではひとつのインデックスをローカル用
と CGI 用と共用できるのが利点です。コマンドラインから検索す
るときには -R オプションを指定すればこの置換を行いません。
別の手法としては
mknmz "
http://foo.bar.jp/~quux/" "
/home/foo/public_html"
のように引数に自分の URL を指定する方法もあります。
これは mknmz がインデックス作成を行う際に対象ディレクトリへ移動し、 &find()
を実行して得られる
./index.html
というファイル名の頭に http://foo.bar.jp/~quux/
をくっつけて URL を作り出します。
毎回これを入力するのが面倒という場合は、 mknmz のソースの頭の方にある
$URL_PREFIX = "\t";
の部分を修正して任意の URL を書いておくことです。例えば
$URL_PREFIX =
"
http://foo.bar.jp/~quux/";
のように設定します。
末尾がディレクトリで終わる URL の表記をしたい場合もあります。普通 は index.html は省略できるように設定されているものです。これは Makefile の OPT_DEFAULT_FILE で指定できます
相対パスの URL を作りたい場合は
mknmz ""
"/home/foo/public_html"
のように URL の指定を "" と null で指定します。
相対パスで URL を作成した場合は検索結果表示に <BASE HREF="..."> を出力するようにします。
namazu.conf で BASE
の設定をしてください。
検索プログラムは (日本語ならば) NMZ.head.ja と NMZ.foot.ja という ヘッダとフッタのファイルを参照します。これらは mknmz を実行した際 にサンプルが作成されますが、必要に応じてメッセージを自分用に書き直 しておきましょう。特に <TITLE> ... </TITLE> は変更する ことを強くお勧めします。
この NMZ.head.ja と NMZ.foot.ja にあるファイル数やキーワード数の記
述されている部分はインデックスを更新した際に、自動的に更新されるよ
うになっているので、 <!-- FILE -->
といったダミー
のタグを消さないでください (そんな情報は必要ないというのなら削除し
ても構いません) 。
一通りの設定が終わったらブラウザから CGI としてアクセスしてみてください。 NMZ.head.ja, NMZ.body.ja, NMZ.foot.ja を元にした表示を行います。 メッセージは自分のサイトに合わせて書き替えてください。 その際は文字コードを必ず ISO-2022-JP で保存します。
-a: すべてのファイルを対象とする -c: 日本語の単語のわかち書きに ChaSen を用いる -e: ロボットよけされているファイルを除外する -h: Mail/News のヘッダ部分をそれなりに処理する -k: 日本語の単語のわかち書きに KAKASI を用いる -m: ChaSen の形態素解析の品詞情報を利用する (名詞のみ登録) -q: インデックス処理の最中にメッセージを表示しない -r: man のファイルを処理する -u: uuencode と BinHex の部分を無視する -x: HTML のヘディングによる要約作成を行わない (文書の先頭から作成) -D: Date:, From: といったヘッダを要約につけない (ディフォルトではつける) -E: 単語の両端の記号は削除する (ディフォルトでは含める) -G: 送り仮名を削除する (ディフォルトでは含める) -H: 平仮名のみの単語は登録しない (ディフォルトでは登録を行う) -K: 記号はすべて削除する (ディフォルトでは登録を行う) -L: 行頭・行末の調整処理を行わない (ディフォルトでは調整を行う) -M: MHonArc で作成された HTML の処理を行わない (ディフォルトでは行う) -P: フレーズ検索用のインデックスを作成しない (ディフォルトでは作成する) -R: 正規表現検索用のインデックスを作成しない (ディフォルトでは作成する) -U: URLのencodeを行わない (ディフォルトでは行う) -W: 日付によるソート用のインデックス作らない (ディフォルトでは作成する) -X: フィールド検索用のインデックスを作らない (ディフォルトでは作成する) -Y: 削除された文書の検出を行わない (ディフォルトでは行う) -Z: 文書の更新/削除を反映しない (ディフォルトでは行う) -A: .htaccess で制限されたファイルを除外する -l (lang): 言語を設定する ('en' or 'ja') -F (file): インデックス対象のファイルのリストを読み込む -I (file): ユーザ定義のファイルをインクルードする -O (dir) : インデックスファイルの出力先を指定する -T (dir) : NMZ.{head,foot,body}.* のディレクトリを指定する -t (regex): 対象ファイルの正規表現を指定する
これらのオプションは -am のようにつなげて指定しても -a -m のように別々に指定しても構いません。
ただし、 -I オプションの後ろにはひとつ空白をあけて次の引数でファイルを指定するようにしてください。
-k -c -m のいずれかのオプションを省略した場合は Makefile の WAKATI
で指定したものが使われます。
-R と -Pオプションはそれぞれ正規表現用インデックスとフレイズ検 索用インデックスを作成したくないときに指定します。
-I オプションに続けてファイルを指定すると、 mknmz 実行時にそのファイルをインクルード (require) します。 これは主に変数を上書きするのに役立ちます。
-F オプションに続けてファイルを指定すると、 インデックスのターゲットのリストを読み込ませることができます。 このリストは一行一ファイルの形式です。たとえば
% find -type f -name '*.html' /foo/bar
のようにして作成してください。なお、 "/foo/bar/baz/" のように最後 が / で終わる (Win32, OS/2 なら \) 行があったときはその部分を find して展開します。このときは $TARGET_FILE に従ってファイルを拾います (v1.3.0.0以降)。
contrib ディレクトリに収録されている Perl版の検索クライアントを使うことによって C のソースをコンパイルすることなしに、検索が行えます。 コマンドラインからの使い方は C言語版とほぼ同じで、また、 CGI としても動作しますから、 プロバイダなどで C コンパイラが使えない環境などで役立つと思います。
KAKASI を用いずに日本語を分解する機能を持っているので、巨大な辞書を用意する必要がないのも特徴です。 検索速度は C言語版に比べてほとんど遜色ありません。
$namazu [options] "query string" [index dir(s)]
のように実行する形になっています。[index
dir(s)]
は検索対象となるインデックスの置いてあるディ
レクトリの指定ですが、 Makefile の INDEXDIR
で
設定したディレクトリの場合は省略できます。オプションは以下の
通りです。
usage: namazu [options] <query> [index dir(s)] -n (num) : 一度に表示する件数 -w (num) : 表示するリストの先頭番号 -s : 短いフォーマットで出力 -S : もっと短いフォーマット (リスト表示) で出力 -v : usage を表示する (この表示) -f (file) : namazu.conf を指定する -h : HTML で出力する -l : 新しい順にソートする -e : 古い順にソートする -a : 検索結果をすべて表示する -r : 参考ヒット数を表示しない -o (file) : 指定したファイルに検索結果を出力する -C : コンフィギュレーション内容を表示する -H : 先の検索結果へのリンクを表示する (ほぼ無意味) -F : <FORM> ... </FORM> の部分を強制的に表示する -R : URL の置き換えを行わない -U : plain text で出力する時に URL encode の復元を行わない -L (lang) : メッセージの言語を設定する ja または en
これらのオプションは必ず -ahs のようにまとめて指定できます v1.1.2.3。
コマンドラインから実行したときはディフォルトでプレインなテキストとして検索結果の表示を行います。 HTML で出力する場合には -h オプションを使います。 CGI から検索したときは結果が一度に表示できないと下の方に [1] [2] [3] のように先の検索結果へ進むためのリンクが作られますが、 コマンドラインから実行したときにはこれらの表示は無意味なので、表示しないようになっています。 この余分な表示を何らかの理由によって強制的に表示させるには -H オプションを使います。 また、コマンドラインから実行したときはディフォルトで <FORM> ... </FORM> を表示させないようになっていますが、 -F をつけると強制的に表示させることができます。
-a オプションは検索結果をすべて表示させます。 これはコマンドラインから実行したときだけの特別なオプションです。 CGI として使う場合はすべてを表示することは敢えてできないようにしています。
検索結果の 21 件目から 40 件目までを表示させたいという場合には
-n 20 -w 20
のように指定します。
-w の値が 21 でないところに注意してください。
-U オプションはコマンドラインから実行して plain text で結果出力する際に URL encode のデコードを行わないためのオプションです。ディフォルトでは行われるようになっています。
namazu.conf および .namazurc ではいくつかの設定が行えます。 namazu は
.namazurc
(CGIのときに便利でしょう)
.namazurc
namazu.conf
(通常は /usr/local/namazu/lib/namazu.conf)
の順で探して見つかればこれをリソースファイルとして読み込みます。
オリジナルは namazu.conf-dist という名前になっているので、 これを namazu.conf または .namazurc という名前にコピーして使います。 オリジナルは残しておいた方が良いでしょう。 これは主に make 時の設定とは違う環境に合わせるときに用います。
各項目と値は TAB で区切ります。これは仕様ですので注意してください。設定の意味は以下の通りです。
INDEX /usr/local/namazu/index
REPLACE /home/foo/public_html/
http://www.hoge.jp/%7Efoo/
/home/foo/public_html/
の部分を
http://www.hoge.jp/%7Efoo/
に置き換えるための設
定です。ローカル用に作ったインデックスを CGI 用に使うときに
役立ちます。コマンドラインから namazu を実行する際には -R オ
プションをつけるとこの設定を無効にできます。BASE
file://localhost/home/foo/bar/documents/
WAKATI /usr/local/bin/kakasi
LOGGING
OFF
LANG ja
必要な設定は make 時に行っているので、特に変わったことをしよ うとしない限り、 namazu.conf で設定をする必要はありません。 make 時に -DNOCONF を指定することでこのファイルの参照を抑制 できます。
namazu をコマンドラインから実行した場合、その出力をパイプで less に渡して眺めることができますが、 せっかくの検索結果を元にリンクを辿っていくことができないのであまり便利ではありません。
namazu -h "keyword" > result.html
のように出力を HTML でファイルに書き出してそれをブラウザで読み込めば検索結果のリンクをたどることができます。
これはちょっと面倒だぞ、という方のために上の処理を自動化してくれるコマンドライン用検索クライアントを馬場肇@京大さんが作ってくださいました。 これは
bnamazu -b "browser" -d "database" "keyword"
のように実行することで、 keyword
を検索し、その結果をテンポラリファイルに保存してそれを自動的に browser
で指定したブラウザに渡して読み込ませるというツールです。
-b browser
を省略するとディフォルトでは Netscape Navigator が呼び出されるようになっています。
-d database
は検索対象とするインデックスのあるディレクトリを指定します。これを省略した場合は namazu
の DEFAULT_DIR
が対象となります。
これはなかなかセコイようでいて、結構便利なツールです。 Namazu のパッケージを展開したときにできる contrib ディレクトリに入っています。ぜひお試し下さい。
コマンドラインから使うのもなんだかなあという方は Mule や X, Win32 から使えるそれぞれの検索フロントエンドを使うと便利でしょう。
CGI として動作させることで WWW 全文検索エンジンになります。 インターネットを通して広く公開しても良いですし、イントラネットとして内輪だけで共有する使い方も考えられます。 普段使い慣れたブラウザで閲覧できるところも利点です。
Mule から検索できるインタフェース (namazu.el) を パッケージに同梱させてもらうことになりました。 namazu.el を作成してくださった まつもとゆきひろさん、やまだあきらさん、馬場肇さんに感謝します。
Namazu の contrib ディレクトリに入っている namazu.el-xxxxxxxx.xx.gz をどこか適当な場所へ
namazu.el という名前で置きます。例えば /home/foo/elisp に置いた場合は .emacs
に
(setq load-path (cons (expand-file-name "/home/foo/elisp") load-path))
(autoload 'namazu "namazu" nil t)
のように記述することで Mule から M-x namazu
で
namazu-mode を呼び出すことができるようになります。詳しい説明は
namazu.el
のペイジを参照してください。とても便利です。
広瀬@NECエンジニアリングさんが Tcl/Tk による GUI な検索クライアント Tknamazuを作ってくださいました。 contrib ディレクトリに tknamazu-XXX.tar.gz という名前でファイルがあります。 使用するには lynx が必要になります。 v2.6 などの古いヴァージョンの lynx では問題があるので新しい 版を用意する必要があります。
Tknamazuの特徴は次の通りです。
詳しくは Tknamazu 付属のドキュメントを参照してください。 また、 広瀬さんによる Tcl/Tk Namazu client のペイジがあるので、こちらを参照すると最新情報が手に入ります。
私の先輩の山下誠二さんが "Search-S for Namazu" という名前の Win32 用の GUI な検索ツールを作ってくださいました。
実行ファイルのサイズが大きいため Namazu の配布パッケージには含まれていません。 最新版は 山下さんのウェブサイト から取ってくることができます。
このツールは Delphi で記述されており、ソースも付属しています。 検索結果は Netscape Navigator および Internet Explorer に渡して表示させることができる他、内部ブラウザで表示することもできます。 この場合はファイルの中身の表示も含めて単体で動作します。
広瀬@NECエンジアリングさんによる Namazu for Win32 と組み合わせることによってWin32 環境での手軽な全文検索ツールとして使えると思います。
まつむらのぞみさんによる Java版の検索クライアントが contrib ディレクトリに収録されています。 こちらも GUI な検索ツールとして動作します。 Java の実行環境を持っている方はぜひお試しください。
これらの NMZ.* のファイルは httpd から参照されない場所に置いておい た方が良いでしょう。NMZ.head.[a-z]{2} と NMZ.foot.[a-z]{2} は検索 プログラムが表示に用いるヘッダとフッタのファイルです。日本語なら `.ja' 、英語なら `.en' のようなサフィックスがつきます。
NMZ.rはインデックスに登録された文書のリストを記録しています。単な るテキストファイルですが、 NMZ.t との整合性が崩れるとインデックス の更新が行えなくなるのでエディタなどで編集することは避けたほうが良 いでしょう。
NMZ.log はインデックス作成のログを保存します。処理した日付、ファイ ルの数、サイズ、追加されたキーワードの数、処理に要した時間が記録さ れます。
NMZ.slog は検索されたキーワードのログを取るファイルです。これは
mknmz 実行時にサイズ 0 のファイルが作成され、ファイルのパーミッショ
ンは -rw-rw-rw-
のように設定されます。このままだと他
のユーザに消されてしまう可能性もあるので、 root 権限を持っている人
は chown nobody
(httpd のユーザ) のようにしておくと良
いかもしれません (普通はそんなに気にする必要はないとは思いますが)。
NMZ.lock は検索にロックをかけるときのファイルです。このファイルが あると検索プログラムはそのインデックスに対して検索を行いません。
NMZ.h は通常約 256 Kbytes になります
Namazu では二度目以降の検索の際に前回に入力されたキーワードと表示 件数および出力フォーマットの設定が残るような仕組みを実現しています。 これは NMZ.head の
<INPUT TYPE="TEXT" NAME="key" SIZE="40">
<OPTION VALUE="10">10
<OPTION VALUE="short">OFF
などの行を見張って適宜書き換えるので、あまりこの辺りはいじらない方 が良いです。
NMZ.slog は検索されたキーワードのログを保存します。ログは
検索されたキーワード TAB ヒット数 TAB ホスト名(or IP アドレ
ス) TAB 日時
のような書式で保存されます。日本語 EUC で保存され、 TAB で区切って いるので、後々テキスト処理を施すのも容易でしょう。例えば
% awk '-F\t' '{ print $1 }' NMZ.slog | sort f| uniq -c |
sort -nr
のようにコマンドラインから実行すれば検索されたキーワードをそれぞれ カウントして数字の大きい順に出力できます。
RFC の 1 - 2200 までの約 75 MB 分の英文のテキストファイルをインデッ クス化した場合、作成される NMZ.* の合計は約 29 MB になりました。日 本語の文書の場合は英文のみの場合とくらべて大きめになります。
インデックスを更新している最中に検索をかけてもまず大丈夫ですが、更 新処理の最後にファイルのリネームを行っているほんの一瞬の間は検索処 理が行われないように NMZ.lock を置いてロックをかけています。
普通に行っていれば特に問題は起こらないはずですが、 NMZ.* ファイル を下手にいじってしまうと更新がうまくいかなくなります。また、インデッ クス作成の途中で強制終了などをして中途半端な NMZ.* ファイルの残骸 が残っていたりすると次にインデックス作成を行う際におかしな動作をす る可能性があります。そのようなときはすみやかに NMZ.* をすべて削除 して最初からインデックス作成をやり直してください。
NMZ.i に登録されているキーワードを一覧表示する専用のツールを添付し ているのでこれを使います。具体的には
% wdnmz NMZ.i
のよう実行すれば (先頭の行の #!/usr/bin/perl
を確認しておいてください)、
単語 TAB その単語が含まれるファイルの数
の書式で標準出力に出力されます。文字コードは日本語 EUC です。例え ば
% wdnmz NMZ.i | wc -l
のように実行すれば登録されている単語の数を確認できます。
v1.1.2 からは別のマシンで作ったバイトオーダの異なるインデックスを 扱うことができるようになりました。通常に検索するだけならば特にイン デックスのバイトオーダの違いを気にする必要はありませんが、インデッ クスを更新する際には問題になります。バイトオーダを変換するツールが 用意されているのでそれを使います(通常はほとんど使う必要はないでしょ う)。
% rvnmz Go
と実行するとカレントディレクトリにあるインデックスのバイトオー ダを変換ができます。
little-endian のインデックスの場合は NMZ.le、 big-endian のインデックスの場合は NMZ.be というファイルが目印として置かれています。
英語でメッセージを表示させるにはいくつかの方法があります。
% namazu -L en
<INPUT TYPE="HIDDEN" NAME="lang" VALUE="en">
とでも指定すれば良いでしょう。
<SELECT> ... </SELECT> で選択させることもできます。
英語のメッセージは NMZ.*.en に保存されています。 適宜修正して使ってください。
Makefile で設定できない細かいカスタマイズについてはソースを直接編集することになります。
カスタマイズが容易にできるように重要な定数/メッセージの定義をソー スの頭の方で行っています。それぞれコメントがついているので、好みに 応じて変更してください。取り返しの付かない変更を行って後悔しないよ うにオリジナルは保存しておいた方が良いでしょう。
インデックス作成を速く行うには Makefile の
OPT_ON_MEMORY_MAX
の値を大きくして make と効果的です。
これは一度にオンメモリで処理するファイルの合計サイズの値ですので、
メモリをたくさん積んでいるマシンの場合はそれに合わせて増やすと良い
でしょう。ディフォルトでは 5 MB 分のファイルをオンメモリで処理する
ように設定しています。
メイリングリストや NetNews のアーカイヴをインデックス化する際には MHonArc のような HTML 変換コンヴァータを利用してからインデックス作成するこ とをお勧めします。これらのコンヴァータを使えば議論のスレッド単位で の相互リンクを張ってくれるので文書のクロスリファレンス性も高まりま すし、 HTML のタグ付けをすることによってスコアリングの品質も向上し ます。このように、素のままのテキストファイルと比べて断然データベー スとしての価値が高まります。
Namazu の配布パッケージのcontrib/
のディレクトリに眞
柄さんが作成された MHonArc 2.2.0用の日本語化パッチ
MHonArc-2.2.0-Japanize-Namazu.patch-1.3a.gz が含まれています。
MHonArcを利用する際はこれをあてると良いでしょう。
Namazu では Mail/News を意識した行頭/行末の処理、 Mail/News の要約作成を行っています。 これとは別にインデックス作成時にオプションを指定することで uuencode の部分を無視することもできます。詳しくはmknmz のコマンドラインオプションを参照してく ださい。
Mail や News の plain なファイルを処理する際は mknmz 実行時に -h とつけると不必要なヘッダを取り除いたり要約に From: と Date: をつけ たりといった処理を行うことができます。 (v1.0.4)また、 MIME の Mutipart で添付されたファイルについては text/plain 以外のものを捨 てる処理をしています。 (v1.1.1)
また、 MHonArc (v2.1.0) に特化したインデックス処理を行うこともでき ます (2.1.0 より古い MHonArc は対応していません)。 MHonArc で作成される HTML ファイルに特有の不必要な部分を削除した り、要約に From: と Date: をつけたりといったことをしています。また、 maillist.html や threads.html といった MHonArc の作成するインデッ クスをスキップします。 (v1.0.4)この処理は自動的に行われますが、 mknmz 実行時に -M と指定することにより抑制することもできます。 (v1.1.1)
mknmz 実行時に -r
オプションをつけると Makefile の
OPT_HELPER_MAN = /usr/bin/jgroff -man -Tnippon
で指定したフィルタを通して man のファイルを扱います。mknmz 内でも フィルタ処理が行われますが、この処理は割といい加減です。
mknmz に -F オプションを指定するとインデックスの対象となるファイル のリストを渡すことができます。このとき、
/home/hoge/foo/
のように末尾が / で終わる行があるとそのディレクトリ内のファイルを 再帰的に取得します。たとえば
/home/hoge/foo/
/home/hoge/bar/
/home/hoge/baz/
のように指定すると /home/hoge/foo, /home/hoge/bar, /home/hoge/baz と3つのディレクトリ以下のファイルを一度にインデックスできます。
(文書化はまだ不十分です。この説明でわかる方だけ挑戦してください)
Makefile の
################################################################## ## Robots.txt OPT_HTDOCUMENT_ROOT = /usr/local/apache/share/htdocs OPT_HTDOCUMENT_ROOT_URL_PREFIX = http://www.foo.domain.jp/ OPT_ROBOTS_EXCLUDE_URLS = ''
を設定して mknmz 実行時に -e オプションをつけてください。Disallow ディレクティヴで指定されたファイルは除外されます。この機能は 國頭さんがコードを 提供してくださいました (Thanks!)。
mknmz に -A オプションを指定して実行してください。 .htaccess内に deny か require valid-user, user, group 行が含まれる場合はそのディ レクトリ以下をインデックスの対象から除外します。
この機能は 國頭さんがコードを 提供してくださいました (Thanks!)。
Namazu では
<FORM METHOD="GET" ACTION="/cgi-bin/namazu.cgi">
のように GET メソッドを使って入力データを渡しています。基本的に GET よりも POST の方が信頼性が高く、広く用いられているのですが、検 索結果のペイジ単位での表示を実現するために GET を使うことにしまし た。実際のところ、検索システムという性質からしてブラウザから巨大な データが送られてくることはまずないので、問題はないと思われます。
ディフォルトで作成される NMZ.head には
<P>
<STRONG>一度に表示する件数:</STRONG>
<SELECT NAME="max">
<OPTION VALUE="10">10
<OPTION SELECTED VALUE="20">20
<OPTION VALUE="30">30
<OPTION VALUE="50">50
<OPTION VALUE="100">100
</SELECT>
<STRONG>文書の要約表示:</STRONG>
<SELECT NAME="format">
<OPTION SELECTED VALUE="long">ON
<OPTION VALUE="short">OFF
</SELECT>
</P>
のように記述され、ブラウザ側から結果表示の件数と出力フォーマットを 指定できるようになっています。
ブラウザから複数のインデックスの中からひとつを選べるように設定する
こともできます。ただし、割とややこしいので仕組みをよく理解している
人でないと難しいかもしれません。まず初回アクセス用の index.html な
どを作成します。その <FORM></FORM>
の中に
<STRONG>検索対象:</STRONG>
<SELECT NAME="dbname">
<OPTION SELECTED VALUE="
foo">
foo
<OPTION VALUE="
bar">
bar
<OPTION VALUE="
baz">
baz
</SELECT>
のような記述をいれておくことで、 foo, bar, baz の中から
データベースの指定ができるようになります。この選択の要素はいくつあっ
ても構いません。
foo が選ばれた時は Makefile の INDEXDIR
で定義されたディレクトリの下にある foo というディレクト
リにある NMZ.* を元に検索することになります。
INDEXDIR
が /usr/local/namazu/index
の場
合は下のようなディレクトリ構造になります。
/ + usr/ + local/ + namazu/ + index/ + foo/ + bar/ + baz/
また、その foo, bar, baz にある各 NMZ.head にもそれぞれ 上のような記述をいれておかなければなりません (SELECTED はつけなく ても良いです)。ACTION の指定についてもすべての NMZ.head で同じ物を 指定しておきます。ディフォルトで作成される NMZ.head にはこのデータ ベース指定の設定は記述されていないので、必要のある人は各自で追加し てください。
<INPUT TYPE="HIDDEN" NAME="dbname" VALUE="foo">
のように INPUT を HIDDEN 属性にしてこっそり指定しておくこともできます。
v1.1.2 からは複数のインデックスに検索をかけて結果をマージして出力 できるようになりました。<FORM> ... </FORM> の中に下のような記述を入れてください。注意点は上のブラウザからインデックスを指定する方法で述べた ものと同じです。
<STRONG>対象インデックス</STRONG><BR>
<UL>
<LI><INPUT TYPE="CHECKBOX" NAME="dbname"
VALUE="foo" CHECKED>foo
<LI><INPUT TYPE="CHECKBOX" NAME="dbname"
VALUE="bar" CHECKED>bar
<LI><INPUT TYPE="CHECKBOX" NAME="dbname"
VALUE="baz" CHECKED>baz
</UL>
このように記述しておくことで foo, bar, baz から複数選択して 検索できます。検索結果に使われる NMZ.head, NMZ.foot は Makefile で INDEXDIR で指定したところにあるものが使われます (または namazu.conf, .namazurc の中で INDEX の項目で指定した ディレクトリにあるもの)。インデックスの指定がひとつだった場 合には個々の NMZ.head, NMZ.foot が使われる点に注意してくださ い。これを回避したい場合にはすべての NMZ.head, NMZ.foot を共 通にしてしまうことです。
CGI に subquery の値を渡すことで実現できます。たとえば以下のように 指定すると良いでしょう。一番下の行は検索結果の「参考ヒット数」の表 示を抑制するためのおまじまないです。
<STRONG>検索対象</STRONG>
<SELECT NAME="subquery">
<OPTION VALUE="">全体
<OPTION VALUE="+url:/^http://foo.bar.jp/aaaa//">aaaaのコーナー
<OPTION VALUE="+url:/^http://foo.bar.jp/bbbb//">bbbbのコーナー
<OPTION VALUE="+url:/^http://foo.bar.jp/cccc//">ccccのコーナー
<OPTION VALUE="+url:/^http://foo.bar.jp/dddd//">ddddのコーナー
</SELECT>
<INPUT TYPE="HIDDEN" NAME="reference" VALUE="off">
subquery には +url: 固定ではなく任意の検索式を指定できます。この機 能は少しややこしいので Namazuに慣れてから挑戦することをお勧めします。
大文字、小文字の区別はありません。foo* のように末尾にア スタリスクを指定することで前方一致検索が可能です。また、単語をスペー ス区切りで並べて書くとアンド検索になります。日本語は KAKASI/ChaSen によって分解され、「日本語情報処理」なら 「日本語」 「情報処理」 のように 2 つの単語に分かれてアンド検索されます。日本語の単語の分 解は完全ではありません。品質は辞書によって決定されます。
全角 (2 bytes) アルファベット/記号はすべて 1 byte として処理されま
す。記号を含む検索も可能で TCP/IP
というような単語の
検索も可能です。ただし、記号の処理は完全ではないので TCP
IP
のように分けてアンド検索をかけた方が取りこぼしがありませ
ん (その代わり余計なファイルまでヒットしてしまう可能性もありますが)。
括弧を含めたアンド検索とオア検索およびノット検索が可能になっており
検索式に & | ! ( )
を用います。記号の代わりに
and/or/not
で指定することも可能です。検索式はひとつづ
つスペース区切りで入力しなければなりません。たとえば
( sed | awk ) ! perl & regexp
( sed or awk ) not perl and regexp
のように指定します。
といった検索ができます。これは「 sed または awk が含まれ、perl は含まれない、そして regexp が含まれる」文書を検索するという 意味になります。括弧のネストもできるので、さらに複雑な検索式 で検索することも可能です。
フレイズをダブルクォーテーションまたは中括弧 '{' '}' で囲むこと でフレイズ検索ができます。ただし、精度は 100%ではありません。とき どきはずれます。たとえば
"SIMPLE MAIL TRANSFER PROTOCOL"
{SIMPLE MAIL TRANSFER PROTOCOL}
のように指定します。
正規表現および中間一致/後方一致の検索も可能です。ただしちょっと 遅いです。日本語も使えます。
*大学
(後方一致)
*ネット*
(中間一致)
/インター?フェ[ーイ]ス/
(正規表現)
"静岡県浜松市"
(フレイズ)
のように指定します。
フィールド指定の検索を行うことができます (フィールド検索用のインデッ クスが作ってあれば) 日本語も使えます。
+date:/Aug 1998/
(1998年 8月のもの)
+from:foo@bar.jp
(差出人が foo@bar.jp)
+subject:"internet message"
(Subject:を文字列で検索)
+subject:{internet message}
(上と同じ)
+subject:/(mule|xemacs|emacs)/
(Subject:を正規表現で検索)
+message-id:<199801240555.OAA18737@foo.bar.jp>
(Message-Id)
+title:amarok
(文書のタイトル)
+author:foo@bar.jp
(文書の著者)
+url:http://foo.bar.jp/
(文書のURL)
のように指定します。
HTML は元々 SGML の一アプリケーションであり、文書の構造を定 義する言語ですから、<H[1-6]> タグによって定義される文 書のヘディング (見出し) の情報を利用することによって簡単に要 約らしきものを作成できます。要約はディフォルトでは 200 文字 に設定されていますから、ヘディングだけを集めて足りない部分は 文書の先頭から補うようにします。また、対象が単なるテキストファ イルだった場合には文書の先頭から 200 文字をそのまま使います。 Namazu ではこのように単純なアプローチを取っています。
ヘディングの情報を元に要約を作成するといこのう手法は対象とな る HTML ファイルに正しく文書の論理構造が定義されていなければ 効果を発揮しません。<H[1-6]> を文字サイズの指定に使っ ているようなペイジではほとんど意味のない要約が作成されてしま うことになります。HTML によって文書の論理構造を定義すること の意義が広く浸透すればこの状態も改善されるでしょう。
ディフォルトでは
<TITLE> 16
<H1> 8
<H2> 7
<H3> 6
<H4> 5
<H5> 4
<H6> 3
<A> 4
<STRONG>, <EM>, <CODE>, <KBD>, <SAMP>, <CITE>, <VAR> 2
のように HTML タグに応じてスコアに重みづけがされています。
これらの値は mknmz.pl の %TAGW
という連想配列に
設定されており、ソースの頭の方で定義されています。
<FONT> などの見栄えを指定する物理タグは論理的な意味を
もたないためスコアに重みづけをしていません。これは Namazu に
限った話ではありませんが、論理タグを使わずにいくら
<FONT> などのタグを使って見栄えのする (それもすべての
ブラウザで通用するわけでもない) ペイジを作ったとしても、検索
システムのインデクサから見ると、まったく文書の論理構造のない
HTML であるので、まともなスコアリング処理はできません。また、
ダイジェスト化の処理を行う検索システムでは一切情報が残らない
ということも起こり得ます。私が言うことでもありませんが、
HTML 自体は論理構造を記述し、文書の見栄えを指定するにはスタ
イルシートを用いるのがスマートな方法です。
実際にウェブ・イジを収集して調べてみたところ、想像以上に
<H[1-6]>
を文字サイズの指定に使っている人
(本文全体を <H1> で囲んだり) が多いことが判明したので、
タグにはさまれる文字列の長さが 128 文字を越える場合は重みづ
けをするのをやめるようにしました。この制限は
$INVALIDLENG
に定義されています。
また <META NAME="keywords" CONTENT="
foo bar">
の foo bar に対しては 32 のスコアがつきます。
これは $METAKEYW
という変数に設定されています。
Namazu ではインデックス作成の際に ", &, <, > および 	-10,  -126 の named entity と numbered entity を復号しています。 < > のようにホワイトスペース区切りで複数指定して最後にセミコロンを打った形式でも大丈夫です。 内部処理を日本語 EUC で行うため ISO-8859-1 の右半分 (0x80-0xff) の記号は処理できません。 同じ理由により I18N 拡張された UCS-4 な numbered entity にも対応不可能です。 また、インデックス作成の際には <IMG> タグの ALT 要素の取り出しを行っています。
インデックス作成の処理は最終的には HTML タグをすべて捨てるのですが、その際、タグによっては単に削除すべきものと空白に変換すべきものとがあります。 例えば、「これは<STRONG>重要</STRONG>です」などというように用いられるタグは削除しますが、「This is foo.<BR>That is bar.」のような用いられ方のタグは単純に削除してしまうと foo.That と単語が繋がってしまうため、空白に変換しておきます。 この設定は mknmz.pl の $NON_SEPARATION_TAGS に定義されています。
行頭/行末の空白/タブ、行頭の > | # : を削除します。 また、行末が日本語で終わる場合は改行コードを無視します (日本語の単語が行末で分断されてしまうのを防ぐ) 。 これら処理は特にメイルのファイルをなどを扱う際に効果を発揮します。 これらのルーチンのアイディアとコードは古川@ヤマハさんがくださいました。 また、英文ハイフォネーションの復元も行います。
Mail/News のファイルを扱う際は「◯◯@△△と申します」のように自分
の名前を名乗る行や、引用時の「◯◯さんは△△の記事において□□時頃
書きました」のような情報、>
などで表される引用部
分をできるだけ要約に含ませないように処理をしています。これらのメッ
セージは要約には含まれませんが、検索対象には入るようになっています。
このアイディアはやまだあきらさんから頂きました。実際にどのように処
理しているか興味のある方はソースで確認してください。
内部処理を ASCII + 日本語 EUC 、出力を ISO-2022-JP で行っています。 JIS X 0201 の右半分 (いわゆる半角カナ) の文字は扱えません。 また、多言語の処理も行えません。
HTML 4.0 Strict DTD に従った HTML を出力します。 文法については石川雅康@W3C さんの作成された jweblint で検証済みです。 出力する HTML を修正する際には正しい HTML を考慮するようにしましょう。 あくまでも検索エンジンなのですから、変に装飾にこだわる必要はないように思われます。 HTML を記述する上で参考になるものを参考文献に挙げているので、それらを参照されることをお勧めします。
v1.1.2.2からはtf idf法によるスコア計算を実装しました。 これは与えられたキーワードが2つ以上あるときに用いられます。
計算式は
tf = 文書に含まれるキーワードの出現回数
N = 全文書数
n = キーワードが含まれる文章の数
idf = log(N/n)
(Inverse Document Frequency)
スコア = tf * idf
のようになっています。これにより多くの文書に含まれるキーワードには 低いスコアがつき、そのキーワードを含む文書が少ない場合には高いスコ アがつくことになります。
A という単語と B という単語をアンドまたはオア検索した場合、それぞ れの単語のスコアを元にスコアの再計算を行います。具体的には、アンド のときは A と B を比べてスコアの小さい方を、 オアのときは A と B の大きい方を新しいスコアとして採用します。例えば "THE BEATLES" と いうキーワードでアンド検索をかけた場合、 "THE" の方のスコアはほと んど意味がないため、小さい方のスコアを重視します。
ChaSen は文章の形態素解析を行い、形態素単位での品詞情報を抽 出できます。Namazu ではこれによって得られた品詞から名詞のみ を有効とし、他をすべて切り捨てる動作をオプションで行えるよう になっています。これによって無駄な単語をインデックスに含むこ となく、スリムなインデックスを作成できます。
記号の処理はなかなか難しい問題です。例えば (foo is
bar.)
のような文があったときに単純にスペース区切りでインデッ
クス化してしまうと "(foo", "is", "bar.)"
のように登録
されてしまい、これでは foo や bar で検索できなくて困ります
("bar*"
とすることで前方一致は引っかかりますが、アル
ゴリズムの性釈上、前方一致以外の部分一致は不可能です) 。
この問題を回避するためには記号をすべて取り払ってしまえば最も楽なの
ですが、 .emacs, TCP/IP
といった記号混じりの単語で検
索したい場合もあります。
Namazu ではインデックス化しようとするファイルに
tcp/ip
のような文があった場合、 "tcp/ip",
"tcp", "ip"
のように 3 つに分解してインデックスに登録します。
tcp/ip から tcp, ip と取り出して登録してもあまり意味がないように
思えるかも知れませんが、 s.takabayashi という文に対して
s.takabayashi だけでなく takabayashi や s & takabayashi でも検
索できるようにとの配慮です。
また、 (tcp/ip)
という文があった場合には
"(tcp/ip)", "tcp/ip", "tcp", "ip"
のように 4 つ
に分解します。<s.takabayashi>, e-mail:
の
ようなものでも同じです。さすがに ((tcp/ip))
の
ように入れ子構造になっている場合の処理は行っていないので
"((tcp/ip))", "(tcp/ip)", "tcp", "ip"
のように
処理されます。最初の例の場合は "(foo", "foo", "is",
"bar.)", "bar.", "bar"
のように登録されるため foo で
も bar でも検索できます。
この手法でもまだ単語の取りこぼしが発生するという点で完全とい
うわけではないのですが (例えば
e-mail:foobar@foo.bar.jp
という文から
foobar@foo.bar.jp
を取り出すことはで
きない) 、そんなに悪くないと思っています。欠点としてはインデッ
クスのサイズが結構大きくなってしまうことですね。検索の柔軟性
を高めようとするとどうしてもゴミが増えてしまいます。
一般的なアプローチとして、記号や数字を一切無視する、検索する意味の ない単語を無視する (助詞などの品詞を捨てる)、ひらがなを無視する、 短い単語を無視する、頻度の異常に高い単語を無視する、 などといった 手法によってゴミを減らすことも考えられますが、 Namazu では小中規模 の全文検索エンジンということでできるだけ多くの単語をインデックスに 含めるように実装しています。また、 mknmz 実行時に -H, -K といった オプションを指定することでひらがなのみからなる単語を無視したり記号 をすべて削除したりといったこともできます。 -m オプションを指定すると ChaSen による品詞情報を利用して名詞のみ を登録といった処理も行えます。
Namazu の検索アルゴリズムは基本的には単純な 2分探索です。高 速化のために些細な工夫をしています。
英和辞書はペイジをめくる側に A-Z まで各アルファベットから始 まる単語のそれぞれの範囲が分かるように階段状に印がつけられて います。ですから stupid という単語を調べるときは s から始ま る単語の範囲の中だけを調べれば良いことになります。
Namazu では先頭の 2 オクテット分の範囲をあらかじめ調べてありますか ら、 st から始まる単語の範囲だけを調べれば良いわけです。 2 オクテット = 16 bit の組み合わせの種類は 65536 あるのですが、 Namazu で扱う実際に有り得る ASCII + 日本語 EUC の 2 オクテットの文 字コードの並びは約 15,000 です。仮に 10 万語の単語のインデックスが あったとして、理想的に単語が分布しているとすれば 100,000 / 15,000 = 約 6 となり、たった 6 つの中から単語を調べれば良いことになります。
実際には単語の分布には相当のばらつきがあるので、そうはうまくいかな いのですが、悪くても数百程度には範囲を絞ることができると思われます。 うまくいけばたった 1 つに絞ることもあり得ます。多くの場合はその中 間くらいでしょう。その絞られた範囲の中で二分探索法を用いて検索しま す。
元々、二分探索法は少ない比較回数で検索が可能なアルゴリズムですから、 10 万語から検索する場合でも最悪 17 回の比較で検索が可能なのですが、 その数をもう少し減らそうというのが Namazu のせこいアプローチです。
本当は正統的なハッシュ法を用いれば、さらに高速な検索も可能なはずな のですが、プログラミング技術と実装との折り合いで、今の手法で妥協し ています。自分では実用的な速度は達成できたと思っています。
ひとつ上の項で説明したように Namazuは二分探索を実装しています。 二分探索ではアルゴリズムの性釈上、中間一致や後方一致は不可能ですから、 別の方法を採るしかありません。
そこで、古川@ヤマハさんが中間一致、後方一致を実現するためのイ ンデックスを考案して pnamazu に実装してくださいました。
C版の namazuでもこれを真似して実装を試みましたが、途中で、ある ことに気付いて中止しました。それは「最近のマシンは速いから登録単語 を全数 grep しても十分実用になるだろう」ということです。
この方法ならば正規表現が使えるし、実装もシンプルになるというわ けでさっそく試してみたところ、事実、十分実用的な (私のところでは 2,3秒くらいです) 速度で検索が可能なことが分かりました。
正規表現は Ruby の
コードを使わせていただいているので (まつもとゆきひろさん Thanks!)、
日本語も扱えます。たとえば /インター?フェ[ーイ]ス/
と
いった指定が可能になっています。
なお、中間一致/後方一致は内部的に正規表現に変換して実現されていま す。これらの機能が不要な場合は NMZ.w を削除してください。
フレイズ検索の実装はかねてからの目標でした。最も問題だったのは 単純に現状のインデックスの構造の延長上に実装するとインデックスのサ イズが巨大になるということでした。良い方法が思いつかずに悩んでいる と、古川@ヤマハさんから次のような助言をいただきました。
「フレイズを構成する個々の単語はすべて AND検索でそのファイルに 存在することが分かっているのだから、調べる必要があるのは単語の並び だけである。精度を多少犠牲にして単語をハッシュ値に変換すればサイズ は小さくなる。」
なるほど、これはいける、ということで実装したのが Namazu のフレー ズ検索です (古川さん Thanks!)。「あやしげな」というのは精度 が 100% ではないことを意味します。
フレイズは 2語単位で 16 bitのハッシュ値に変換して記録しているの で、たとえば "foo bar baz" というフレイズで検索すると
...
foo bar ...
... bar baz
のように "foo bar" と "bar baz" の含まれるファイルもヒットして しまいます。これはちょっと困ったことですが、少なくとも foo & bar & baz で検索するよりは候補を絞れます。
理想的には "foo bar baz" を確実に検索できた方が望ましいのですが、 インデックスのサイズとの兼ね合いもあるので難しいところです。もっと 良い方法が見つかれば置き換えたいと思っています。
フレイズ用のインデックス NMZ.p のサイズは転置ファイル NMZ.i よりは 小さくなります。また、これの補助インデックスとして 256KB (int = 32bitで計算) を必要とします。
なお、フレイズ検索用インデックスの作成にはメモリを割と消費するので 注意が必要です。FAQ の mknmz で Out of memory! がでてしまいま すを参照してみてください。
Mail/News を検索するとき、 Subject:
,
From:
, などを指定して検索が可能になると特定の人
の投稿のみを抽出できたます。
そういう要望からフィールド指定の検索を実装することになりました。元々 は NMZ.i に記録されるスコアの情報に細工して 16bitほどのフィールド 情報を持たせるという割と凝った方法を考えていたのですが、Namazu メイリングリストにてそのことを提案すると、加藤裕@NTTデータさん からもっと楽な方法を示唆していただきました。
フィールドの情報は NMZ.field.{subject,from,date,message-id,...) と いったファイルに記録して、その形式は単なる行指向のテキストファイル です。検索時にはこのファイルを正規表現のエンジンで grep して検索を 行います。
極めて安易な実装ですが、それなりに使えると思います :-)。
現在のところ Subject: (Title:) , From: (Author:) , Date:, Message-Id:, Url: (Path:), Newsgroups: のフィールドが検索可能です。
v1.3.0.0 より前のヴァージョンではインデックスは文書の追加しかできず、 ウェブペイジなど、頻繁に更新される文書を対象とする場合には毎回全体 のインデックスを作り直さなければならず、不便でした。 v1.3.0.0 からは文書の更新/削除に対応したインデッックスのアップデー トを行うことができます。
この仕組みは実際にインデックスから登録済の文書を更新/削除するので はなく、欠番情報を記録することによって実現されています。つまり、イ ンデックスに記録された元の情報はそのままで、単にその文書の IDが欠 番になるだけです。この情報は NMZ.t に記録され、検索時に参照されま す。また、文書の日付情報と共用されています。
文書の更新/削除を含むインデックスの更新を繰り返していくと欠番が増 えて記録効率が悪くなっていきます。そこで、古川@ヤマハさん作の欠 番を詰めるツール gcnmz の出番です。使い方は
% gcnmz /doko/soko/NMZ
のようにゴミ掃除対象の NMZ.* ファイルのパスをファイル名の NMZまで を指定します (拡張子の前まで)。このツールはまでテストが不十分なの で十分注意して使ってください。なお、ゴミ掃除する前の元のファイルは *.BAK として残ります。 *.BAK を復元したいときは
% ls NMZ.*.BAK |perl -nle 's/\.BAK$//;rename("$_.BAK", $_)'
のように実行すると良いでしょう。
なお、この欠番方式のアイディアは古川竜雄@日本HPさんからいただきま した。 1997年の 11月頃の話です。
v1.3.0.0 からは文書の日付によって検索結果を新しい順/古い順に ソートできます。 NMZ.t を参照するので -W オプションをつけてインデックスを作った場合 にはできません。
昔の版にあったファイル名に連番が含まれるものを擬似的に新しい順/ 古い順にソートする機能 (検索対象となるインデックスが単一の場合のみ 有効) はそのまま残っているので -W オプションつきでインデックスを作っ たときでもこの機能は有効です。
Mail/News の Date: ヘッダに合わせてファイルのタイムスタンプを修正 するツール mailutime を添付したので必要な人は使ってください。 MHonArc を使っている人は -modtime オプションで同じことができます。
v1.2.0.2 からは検索時に日本語のわかち書きを自前で行うようになりま した。これにより KAKASI/ChaSen を呼び出す必要がなくなり、処理速度 が上がりました。NMZ.i を辞書の代わりに参照して実現しています。文字 列の左から最長一致で分割しているだけです。
<META NAME="keywords" CONTENT="
foo bar">
のキーワードは特にスコアを高く計算
<IMG>
タグの ALT エレメントを抽出する
ToDoファイルにまとめました。
将来的には HTML タグを利用したスコアの重みづけ、要約の作成の処理を応用して SGML 文書を対象とした検索システムを作るのも面白そうだと思っています。
初期の段階から開発に協力して頂き、数々の助言をくださった馬場肇@京大さん、 やまだあきらさん、 たくさんの素敵なコードを追加してくださった古川令@ヤマハさん、 HTML およびテキスト処理に関していろいろと教えてくださった石川雅康@W3Cさん、 QKC のコードを引用または参考にすることを承諾してくださった佐藤公彦@東大さん、 全文検索システムの開発のきっかけとなった httpdown の作者くまがいまさあき@東北大さん、 Win32 対応用のコードをくださった林卓司@エフエフシーさん、 広瀬@日本電気エンジニアリングさん、 Makefile を作成してくださった佐藤文優@cij.co.jp さん、 Ruby の正規表現のコードを使わせてくださったまつもとゆきひろさん、 バグ報告/動作報告をしてくださったみなさん、 Namazu mailing list のみなさん。
プログラムに改良すべき点を見つけた方はお知らせ頂けるとありがたいです。 特にバグに関してはできる限り対処していきたいと思っています。 このささやかな検索システムが情報検索の場面で少しでもお役にたてれば幸いです。
ChangeLog を参照してください。