Estraierバージョン1基本仕様書

Copyright (C) 2003-2004 Mikio Hirabayashi
Last Update: Mon, 28 Jun 2004 02:02:18 +0900

目次

  1. 概要
  2. インストール
  3. 転置インデックスの管理
  4. 検索用ユーザインタフェース
  5. メタ検索システム
  6. 助言
  7. バグ
  8. ライセンス

概要

Estraierは個人用途向けの全文検索システムである。いわゆる全文検索とは、数多くの文書の中から、特定の語句を含むいくつかの文書を見つけ出すことである。EstraierはWebサイト上の文書を対象とした全文検索システムを実現することを主な目的とする。Googleのような検索システムを個人のサイトやイントラネットで利用できるようにしたものである。Estraierは以下の特長を持つ。

  1. 検索が高速である。
  2. 検索結果が見やすい。
  3. 関連文書検索ができる。
  4. 様々な言語が扱える。
  5. 様々なファイル形式が扱える。
  6. 大量の文書を扱える。
  7. 導入が簡単である。

Estraierは転置インデックスと呼ばれるデータベースを用いて高速な全文検索を実現する。転置インデックスはサイトの管理者がWebサーバの動作するコンピュータの上で作業することによって作成される。ユーザはその際に設置されたCGIスクリプトにWebブラウザを用いてアクセスして検索を行う。ユーザインタフェースは簡単なテンプレートを編集することによってカスタマイズすることができる。全文検索機能を備える簡易Webサーバも提供される。

ユーザがWebページ上の入力フォームに検索フレーズを入力すると、その条件に該当する文書のタイトルやURLのリストが表示される。各文書に含まれるテキストの要約も同時に表示される。要約は、検索語の周辺の文を抽出して生成される。要約に含まれる検索語はハイライトされて表示される。検索結果の各文書は、検索語に対するスコアの降順で並べられる。スコアは文書中に占める検索語の数や割合に基づいて求められる。

Estraierは関連文書検索も実装する。検索結果として得られたある文書と関連する内容の文書のリストを提示する機能である。検索結果は関連度の降順で並べられる。関連度はベクトル空間モデルに基づいて算出される。簡単に言えば、語の出現傾向が似た文書を検索できるということである。

EstraierはUnicode(UCS-2)で文字を表現するので、英語などのヨーロッパの言語だけでなく、日本語などのアジアの言語も扱うことができる。現在のバージョンでは、ヨーロッパの言語と日本語のテキストを実用的な精度で解析することができる。

ローカルファイルシステムにあるファイルからテキストを抽出する機能がEstraierには組み込まれている。サポートするフォーマットはプレーンテキストとHTMLとMIME(電子メールとMHTML)である。それだけでなく、任意の外部コマンドを呼び出すことによって様々なフォーマットのファイルを処理することができる。例えば、`wvWare' を用いてMS-Wordのファイルを処理したり、`pdftotext' を用いてPDFのファイルを処理することができる。

Estraierは10万を越える文書を対象とした転置インデックスを構築することができる。扱える文書数の上限はソフトウェアとしては持たないが、ハードウェアの能力に依存して転置インデックスの構築や更新にかかる時間が決まるので、それに応じて実運用上の制限がかかることになる。一方、検索に要する時間は、転置インデックスの規模に関わらず、ほぼ一定である。登録文書数が10万件程度ならば1秒以下で検索結果が提示できるだろう。

Estraierの導入はとても簡単である。ほとんどの場合、インストール作業は20分以内にできるだろう。転置インデックスを作成するには、コマンドを1回か2回実行するだけでよい。数分から数時間程度待つと転置インデックスができあがる。あとは、設置されたCGIスクリプトにアクセスするだけで、全文検索を楽しむことができる。

EstraierはLinux、Solaris、HP-UX、FreeBSD、NetBSD、OpenBSD、Mac OS XおよびWindows(Cygwin)で利用できる。その他のUNIX系のOSでも利用できる。EstraierはGNU General Public Licenseに基づくフリーソフトウェアである。


インストール

準備

ソースパッケージを用いてEstraierをインストールするには、GCCのバージョン2.8以降と `make' が必要である。これらはLinuxや各種BSDには標準的にインストールされている。

EstraierはGNUのlibiconvを利用しているので、予めそれをインストールしておく必要がある。システムがデフォルトでlibiconvを備えている場合もあるが、GNUのlibiconvの最新版を利用した方がよい。また、1.9.1より前のバージョンにはメモリリークの問題があるので注意すべきである。GNUのlibiconvは以下のサイトから入手することができる。

Estraierはzlibを利用しているので、予めそれをインストールしておく必要がある。zlibは多くのシステムにデフォルトでインストールされている。zlibは以下のサイトから入手することができる。

Windows上でEstraierをビルドする場合、Cygwin環境が必要である。Cygwinについて不慣れな場合はEstraierのバイナリパッケージを利用した方がよい。Cygwinは以下のサイトから入手することができる。

Estraierの配布用アーカイブファイルを展開したら、生成されたディレクトリに入ってインストール作業を行う。

インストール

ビルド環境を設定する。

./configure

プログラムをビルドする。Windowsでは、代わりに `make win' とする。

make

プログラムの自己診断テストを行う。

make check

プログラムをインストールする。作業は `root' ユーザで行う。Windowsでは、代わりに `make install-win' とする。

make install

結果

一連の作業が終ると、以下のファイルがインストールされる。

/usr/local/bin/estindex
/usr/local/bin/estserver
/usr/local/bin/estxview
/usr/local/bin/estmbtomh
/usr/local/bin/estpdfhtml
/usr/local/bin/estdochtml
/usr/local/bin/estxlshtml
/usr/local/bin/estppthtml
/usr/local/bin/estmanhtml
/usr/local/bin/estgzhtml
/usr/local/bin/estxdwhtml
/usr/local/bin/estxdthtml
/usr/local/bin/estautoreg
/usr/local/libexec/estsearch.cgi
/usr/local/libexec/estmerge.cgi
/usr/local/share/estraier/estxview.dtd
/usr/local/share/estraier/estxview.css
/usr/local/share/estraier/estxview.xsl
/usr/local/share/estraier/estsearch.conf
/usr/local/share/estraier/estsearch.tmpl
/usr/local/share/estraier/estsearch.top
/usr/local/share/estraier/estmerge.conf
/usr/local/share/estraier/estmerge.tmpl
/usr/local/share/estraier/estmerge.top
/usr/local/share/estraier/locale/...
/usr/local/share/estraier/skins/...

始めはインストールに関してはこれだけ知っていればよい。以下に示す設定オプションは読み飛ばし、転置インデックスの管理の項目に進んでかまわない。

Webサーバの設定

Webサーバの設定についてはこの文書では説明しない。各サーバやプロバイダの説明書を参照し、CGIスクリプトが利用できるように設定しておくこと。CGIが利用できるならば、WebサーバはApacheでもMicrosoft IISでもAnHTTPdでも何でもよい。Estraierには、Webサーバに全文検索機能を統合した検索サーバも付録されているので、それを利用してもよい。

正規表現の利用

デフォルトだと検索語の指定は完全一致しかできないが、正規表現の機能を用いるとワイルドカードや正規表現を使った検索を行うことができる。正規表現を有効にするには、ビルド環境の設定を以下のように行えばよい。

./configure --enable-regex

正規表現の機能はGNUの標準ライブラリ(glibc)には組み込まれているが、そうでないライブラリを用いる場合は、GNU regexを用いるとよい。GNU regexをライブラリにしたものは以下のサイトから入手することができる。

ダイナミックリンクされたフィルタの利用

テキスト抽出の際に外部コマンドを呼び出す際には、システムのシェルを介してコマンドを実行するオーバーヘッドがかかる。ダイナミックリンクライブラリで実装されたフィルタ関数を呼び出すようにすると、その問題を解決できる。Estraierでダイナミックリンクされたフィルタを利用するには、ビルド環境の設定を以下のように行えばよい。

./configure --enable-dlfilter

Estraierはダイナミックリンクライブラリのために `dlopen' システムコールを用いている。少なくとも、それはLinux、FreeBSD、Solaris、HP-UXで実装されている。

テキスト解析のオプション

デフォルトでは、ヨーロッパ系のテキストは空白文字と各種記号によって単語が区切られる。空白文字だけを区切り文字として扱いたい場合は、ビルド環境の設定を以下のように行えばよい。

./configure --enable-strict

デフォルトでは、単語を抽出する際に `a'、`the'、`to' などの一般的すぎる語は禁止語として除外される。この振る舞いが好ましくない場合は、ビルド環境の設定を以下のように行えばよい。

./configure --disable-stopword

アジア系言語のテキストから単語を抽出する際には、テキストを「アルファベット」「平仮名」「片仮名」「ハングル」「CJK統合漢字」「その他」にわけ、それぞれの連続した文字列を単語として扱う。アルファベットと片仮名とハングルとCJK統合漢字のみが転置インデックスのキーとして登録される。この方法でもそれなりの精度にはなるが、用言や平仮名の名詞や連接した名詞を適切に扱えないという欠点がある。日本語に関しては、ChasenもしくはKakasiを用いることで、より精度の高い単語抽出を行うことができる。

Chasenは以下のサイトから入手することができる。

EstraierでChasenを利用するには、Chasenのバージョン2.2.9以降をインストールした上で、ビルド環境の設定を以下のように行えばよい。

./configure --enable-chasen

Chasenのバージョン2.3以降は一部がC++言語で記述されているので、環境によってはビルドに失敗することがある。そのような場合は、2.2.9を利用するとよい。

Kakasiは以下のサイトから入手することができる。

EstraierでKakasiを利用するには、Kakasiのバージョン2.3.4以降をインストールした上で、ビルド環境の設定を以下のように行えばよい。

./configure --enable-kakasi

Chasenは形態素解析器であり、品詞の概念に基づいた精度の高い単語抽出を行うことができる。また、活用語を正規化して扱うことができる。Kakasiは単純な漢字かな変換プログラムであり、Chasenのような精度は期待できないが、高速に動作する。ChasenとKakasiを同時に利用することはできない。


転置インデックスの管理

典型例

全文検索を利用可能にするには、先に転置インデックスを作っておく必要がある。例えば、`/home/mikio/public_html' にWebのコンテンツが置いてあり、同じ場所でCGIスクリプトが実行できるならば、以下の手順を行えばよい。

cd /home/mikio/public_html
estindex register casket
estindex relate casket

すると、`/home/mikio/public_html' 以下にあるHTMLとプレーンテキストとMIMEの全てのファイルがデータベースに登録される。転置インデックスは `casket' という名前のディレクトリとして作成される。

Webサイトに更新があった場合は、以下の手順を行えばよい。

cd /home/mikio/public_html
estindex purge casket
estindex register casket
estindex optimize casket
estindex relate casket

すると、Webサイトから削除された文書は転置インデックスからも削除され、新規の文書や更新された文書は転置インデックスにも反映される。

始めは転置インデックスの作成に関してはこれだけ知っていればよい。以下に示す用法は読み飛ばし、検索用ユーザインタフェースの項目に進んでかまわない。

用法

転置インデックスを管理するコマンド `estindex' の用法は以下である。このコマンドは用途に応じた複数のサブコマンドから構成される。サブコマンド名は第2引数で指定する。接尾辞の指定で `*' を用いると、全てのファイルがマッチするようになる。文字コード名には、`UTF-8' や `Shift_JIS' など、IANAに登録された正式名称を用いる。外部コマンドをフィルタとして呼び出す際には、第1引数で入力ファイル名が指示され、第2引数で出力ファイル名が指示され、環境変数 `ESTORIG' で元来のファイル名が指示される。外部コマンド名が `@' で始まっている場合、外部コマンドを呼び出す代わりに先頭の `@' を除いた名前のダイナミックリンクライブラリで定義された `estfilter' という名前の関数を呼び出す。

転置インデックスを作成したり、更新するには、`register' サブコマンドを用いる。

estindex register [-list file] [-force] [-wmax num] [-tsuf sufs] [-hsuf sufs] [-msuf sufs] [-xsuf sufs type cmd] [-xt] [-xm] [-enc code] [-pt code] [-ft code] [-plute] name [dir]
`name' は転置インデックスの名前を指定する。
`dir' は登録対象のファイルを収めたディレクトリを指定する。省略した場合はカレントディレクトリが指定される。指定したディレクトリは再帰的に探索され、シンボリックリンクも追跡される。
`-list' オプションが指定されると、名前が `file' のファイルを読み込み、その各行に書かれたパスのファイルが登録される。`file' が `-' の場合は標準入力が読み込まれる。このオプションをUNIXの `find' コマンドと組み合わせて使うと便利である。
`-force' オプションが指定されると、既に登録されていて更新されていないファイルも再登録する。
`-wmax' オプションが指定されると、登録する各文書から、`num' で指定した語数だけが要約用の情報として記録される。デフォルトでは全ての語が要約用に登録される。転置インデックスのサイズを小さくし、検索の応答時間を短縮したい場合にはこのオプションが有用である。
`-tsuf' オプションは、プレーンテキストとして扱うファイルの接尾辞を指定する。`sufs' は接尾辞をカンマ区切りで指定する。デフォルトは、 `-tsuf .txt,.asc' と同義である。
`-hsuf' オプションは、HTMLとして扱うファイルの接尾辞を指定する。`sufs' は接尾辞をカンマ区切りで指定する。デフォルトは、 `-hsuf .html,.htm' と同義である。
`-msuf' オプションは、MIMEとして扱うファイルの接尾辞を指定する。`sufs' は接尾辞をカンマ区切りで指定する。デフォルトは、 `-msuf .eml,.mht' と同義である。
`-xsuf' オプションは、任意の外部コマンドで処理するファイルの接尾辞を指定する。`sufs' は接尾辞をカンマ区切りで指定する。`type' はメディアタイプを指定する。`cmd' は元のデータをHTMLに変換するコマンドを指定する。
`-xt' オプションが指定されると、外部コマンドの出力をプレーンテキストとして扱う。
`-xm' オプションが指定されると、外部コマンドの出力をMIMEとして扱う。
`-enc' オプションは、登録するファイルの文字コードを `code' で指定したものにする。デフォルトでは、抽出したテキストに応じて文字コードを自動判定する。
`-pt' オプションが指定されると、各登録文書のタイトルがローカルファイルシステムのパスで上書きされる。ファイルシステムの文字コードは `code' で指定する。
`-ft' オプションが指定されると、各登録文書のタイトルがローカルファイルシステムのファイル名で上書きされる。ファイルシステムの文字コードは `code' で指定する。
`-plute' オプションが指定されると、大規模なサイトを想定してRAMやディスクが贅沢に使われる。
デフォルトでは、既に転置インデックスに登録された文書を登録しようとした場合、前に登録した時間と該当のファイルの最終更新時間を比較し、後者が新しければ上書きで登録し、そうでなければ無視される。

転置インデックスに関連文書検索用のスコア情報を追加するには、`relate' サブコマンドを用いる。

estindex relate [-force] name [prefix]
`name' は転置インデックスの名前を指定する。
`prefix' は対象文書のURIの接頭辞を指定する。省略すると全ての文書について処理を行う。
`-force' オプションが指定されると、処理対象の全文書のスコア情報を既にスコア情報が登録されているかに関わらず更新する。
関連文書検索が不要ならばこのサブコマンドを実行する必要はない。

サイトから削除された文書を転置インデックスからも削除するには、`purge' サブコマンドを用いる。

estindex purge [-force] name [prefix]
`name' は転置インデックスの名前を指定する。
`prefix' は対象文書のURIの接頭辞を指定する。省略すると全ての文書について判定を行う。
`-force' オプションが指定されると、処理対処の全文書をファイルの有無に関わらず転置インデックスから削除する。

転置インデックスの更新で生じた不要な情報を削除するには、`optimize' サブコマンドを用いる。

estindex optimize name
`name' は転置インデックスの名前を指定する。

転置インデックスの情報を得るには、`inform' サブコマンドを用いる。

estindex inform name
`name' は転置インデックスの名前を指定する。

複数の転置インデックスをマージするには、`merge' サブコマンドを用いる。

estindex merge name elems...
`name' は転置インデックスの名前を指定する。
`elems' は要素となる転置インデックスの名前を指定する。

ファイルからのテキスト抽出と単語分割のテストを行うには、`pree' サブコマンドを用いる。

estindex pree [-h] [-m] [-x type cmd] [-xt] [-xm] [-enc code] [-pt code] [-ft code] [file]
`file' は対象のファイルを指定する。省略すると標準入力を読み込む。
`-h' オプションが指定されると、入力をHTMLとして扱う。デフォルトはプレーンテキストである。
`-m' オプションが指定されると、入力を電子メールとして扱う。デフォルトはプレーンテキストである。
`-x' オプションは、任意の外部コマンドでファイルを処理する際に用いる。`type' はメディアタイプを指定する。`cmd' は元のデータをHTMLに変換するコマンドを指定する。
`-xt' オプションが指定されると、外部コマンドの出力をプレーンテキストとして扱う。
`-xm' オプションが指定されると、外部コマンドの出力をMIMEとして扱う。
`-enc' オプションは、登録するファイルの文字コードを `code' で指定したものにする。デフォルトでは、抽出したテキストに応じて文字コードを自動判定する。
`-pt' オプションが指定されると、各登録文書のタイトルがローカルファイルシステムのパスで上書きされる。ファイルシステムの文字コードは `code' で指定する。
`-ft' オプションが指定されると、各登録文書のタイトルがローカルファイルシステムのファイル名で上書きされる。ファイルシステムの文字コードは `code' で指定する。

Estraierのバージョン情報を見るには、`version' サブコマンドを用いる。

estindex version
引数やオプションは存在しない。

各サブコマンドは、正常に完了した際には 0 を返し、一度でもエラーが起きた場合は 1 を返す。動作中にコマンドを終了させたい場合は、SIGINTシグナル(Control-C)、SIGQUITシグナル(Control-/)、SIGTERMシグナルのいずれかを一度だけ送ればよい。そうすると、データベースを正常に閉じてから動作を終了する。他の手段で強制終了させるとデータベースが壊れる可能性がある。

テキストと属性の抽出

プレーンテキストを解析する際には、以下の手順が実行される。

  1. 文字コードを自動判定し、UTF-8に正規化する。
  2. テキスト全体を登録文書のテキストとして抽出する。行頭の引用記号は削除し、折り返された行は連結する。
  3. ファイルの最終更新時刻を登録文書の `date' 属性として抽出する。
  4. 登録文書の `type' 属性を `text/plain' にする。
  5. 判定した文字コード名を登録文書の `encoding' 属性として抽出する。
  6. データのサイズを登録文書の `size' 属性として抽出する。

HTMLを解析する際には、以下の手順が実行される。

  1. 文字コードを自動判定し、UTF-8に正規化する。
  2. `meta' 要素によって文字コードの指定がなされている場合、文字コードの正規化をやりなおす。
  3. データをタグとテキストに分離する。
  4. `body' 要素に含まれるテキストを登録文書のテキストとして抽出する。
  5. `title' 要素に含まれるテキストを登録文書の `title' 属性として抽出する。
  6. `meta' 要素の `name' 属性の値が `author' の場合、その `content' 属性の値を登録文書の `author' 属性として抽出する。
  7. ファイルの最終更新時刻を登録文書の `date' 属性として抽出する。
  8. 登録文書の `type' 属性を `text/html' にする。
  9. 判定した文字コード名を登録文書の `encoding' 属性として抽出する。
  10. データのサイズを登録文書の `size' 属性として抽出する。

MIMEを解析する際には、以下の手順が実行される。

  1. ヘッダとメッセージボディを分離する。
  2. `Content-Type' ヘッダによってメディアタイプと文字コードを判定する。
  3. メッセージボディの文字コードとヘッダによる指定が矛盾している場合、文字コードの正規化をやりなおす。
  4. `Subject' ヘッダの値を登録文書の `title' 属性として抽出する。
  5. `From' ヘッダの値を登録文書の `author' 属性として抽出する。
  6. `To' ヘッダの値を登録文書の `recipient' 属性として抽出する。
  7. `Cc' ヘッダの値を登録文書の `multicast' 属性として抽出する。
  8. `Date' ヘッダの値を登録文書の `date' 属性として抽出する。
  9. 登録文書の `type' 属性を `message/rfc822' にする。
  10. 判定した文字コード名を登録文書の `encoding' 属性として抽出する。
  11. メッセージボディをプレーンテキストもしくはHTMLとして解析する。メディアタイプがマルチパートの場合、その最初のパートを対象にして上述の処理を再帰的に適用する。

各形式において、登録文書の `title' 属性が抽出されず、かつファイル名の文字コードがUS-ASCIIの場合、そのファイル名が `title' 属性として扱われる。

フィルタプログラム

Estraierのソースパッケージには、PDFのファイルを扱うための `estpdfhtml' と、MS-Wordのファイルを扱うための `estdochtml' と、MS-Excelのファイルを扱うための `estxlshtml' と、MS-PowerPointのファイルを扱うための `estppthtml' と、UNIXの `man' のファイルを扱うための `estmanhtml' と、GZIPまたはZIP形式で圧縮されたプレーンテキストやHTMLを扱うための `estgzhtml' と、DocuWorksのファイルを扱うための `estxdwhtml' と、Windows上で様々なファイルを扱うための `estxdthtml' が付属する。これらは転置インデックスを作成する際のフィルタプログラムとして呼び出される。いずれも、第1引数で指定されたファイルを読み込み、そのデータをHTMLに変換し、第2引数で指定されたファイルに書き込むという機能を持つ。

`estpdfhtml' を利用するには、`pdftotext' を予めインストールしておく必要がある。これはUNIX上で動作する。通常、以下のようなコマンドでPDFのファイルを転置インデックスに登録することができる。

estindex register -tsuf "" -hsuf "" -msuf "" \
  -xsuf .pdf application/pdf estpdfhtml casket

`estdochtml' を利用するには、`wvWare' を予めインストールしておく必要がある。これはUNIX上で動作する。通常、以下のようなコマンドでMS-Wordのファイルを転置インデックスに登録することができる。

estindex register -tsuf "" -hsuf "" -msuf "" \
  -xsuf .doc application/msword estdochtml casket

`estxlshtml' を利用するには、`xlhtml' を予めインストールしておく必要がある。これはUNIX上で動作する。通常、以下のようなコマンドでMS-Excelのファイルを転置インデックスに登録することができる。

estindex register -tsuf "" -hsuf "" -msuf "" \
  -xsuf .xls application/vnd.ms-excel estxlshtml casket

`estppthtml' を利用するには、`ppthtml' を予めインストールしておく必要がある。これはUNIX上で動作する。通常、以下のようなコマンドでMS-PowerPointのファイルを転置インデックスに登録することができる。

estindex register -tsuf "" -hsuf "" -msuf "" \
  -xsuf .ppt application/vnd.ms-powerpoint estppthtml casket

`estmanhtml' を利用するには、`groff' を予めインストールしておく必要がある。これはUNIX上で動作する。通常、以下のようなコマンドで `man' のファイルを転置インデックスに登録することができる。

estindex register -tsuf "" -hsuf "" -msuf "" \
  -xsuf .1,.2,.3,.4,.5,.6,.7,.8 application/x-troff-man estmanhtml casket

`estgzhtml' を利用するには、`gzip' を予めインストールしておく必要がある。これはUNIX上で動作する。通常、以下のようなコマンドでGZIPまたはZIP形式で圧縮されたファイルを転置インデックスに登録することができる。

estindex register -tsuf "" -hsuf "" -msuf "" \
  -xsuf .txt.gz,.asc.gz,.txt.zip,.asc.zip,.html.gz,.htm.gz,.html.zip,.htm.zip \
      text/html estgzhtml casket

`estxdwhtml' を利用するには、`xdw2text' を予めインストールしておく必要がある。これはUNIX上で動作する。通常、以下のようなコマンドでDocuWorksのファイルを転置インデックスに登録することができる。

estindex register -tsuf "" -hsuf "" -msuf "" \
  -xsuf .xdw application/vnd.fujixerox.docuworks estxdwhtml casket

`estxdthtml' を利用するためには、`xdoc2txt' を予めインストールしておく必要がある。これはWindows上で動作し、PDF、RTF、MS-Word、MS-Excel、MS-PowerPointなどのファイルを処理することができる。通常、以下のようなコマンドで利用する。

estindex register -ft Shift_JIS -tsuf "" -hsuf "" -msuf "" \
  -xsuf .pdf,.rtf,.doc,.xls,.ppt application/octet-stream estxdthtml casket

各フィルタが依存するプログラムは、それぞれ以下のサイトから入手できる。使用条件についてはそれぞれのライセンスを参照すること。

上記以外にも、ユーザ独自のフィルタプログラムを利用することができる。フィルタプログラムの実装言語は何でもよく、CでもPerlでもシェルでもよい。


検索用ユーザインタフェース

典型例

ユーザに全文検索システムを公開するためには、CGIスクリプトとその設定ファイルを設置する。例えば、`/home/mikio/public_html' に転置インデックスが置いてあり、同じ場所でCGIスクリプトが実行できるならば、以下の手順を行えばよい。

cd /home/mikio/public_html
cp /usr/local/libexec/estsearch.cgi .
cp /usr/local/share/estraier/estsearch.conf .
cp /usr/local/share/estraier/estsearch.tmpl .
cp /usr/local/share/estraier/estsearch.top .

`estsearch.cgi' はユーザがアクセスすべきCGIスクリプトである。各種設定ファイルの内容は、テキストエディタで編集することができる。始めはそれらを変更する必要はない。とりあえず `estsearch.cgi' にWebからアクセスしてみてほしい。

検索条件

検索条件の入力フォームに検索語を入力して `Search' ボタンを押すと検索が実行される。単一の語を入力した場合には、その語を含む文書が提示される。複数の語を入力した場合には、その全ての語を含む文書が提示される。検索語の間は半角または全角の空白文字で区切る。

検索語の第二語目以降には、以下の演算子を前置して用いることができる。各演算子と検索語の間は空白で区切られている必要がある。演算子の優先順位は全て同等で、左結合で評価される。

[and] word 指定した語を含まない文書を結果から除外する。これは演算子を指定しなかった場合と同じ動作である。
[or] word 指定した語を含む文書を結果に追加する。
[not] word 指定した語を含む文書を結果から除外する。

例えば、`apple' と `orange' の両方を含むという条件なら、以下のようになる。

apple orange

上記と同じ条件を演算子を使って表現すると、以下のようになる。

apple [and] orange

`apple' か `orange' のどちらかを含むという条件なら、以下のようになる。

apple [or] orange

`apple' を含むが `orange' を含まないという条件なら、以下のようになる。

apple [not] orange

`apple' と `orange' の両方を含むが、`grape' を含まないという条件なら、以下のようになる。

apple [and] orange [not] grape

`apple' と `orange' のどちらかを含み、かつ `grape' を含み、かつ `melon' を含まないという条件なら、以下のようになる。

apple [or] orange [and] grape [not] melon

`apple' を含むが、 `orange' も `grape' も含まないという条件なら、以下のようになる。

apple [not] orange [not] grape

`apple' を含むが、`orange' と `grape' の両方を含むということはないという条件は、通常の方法では表現できない。

空白で区切っていなくても、複数の語からなる検索語は自動的に分割されることがある。その際には、二語目以降には直前の演算子か、なければ `[and]' が適用される。この性質を利用して、自然文を検索条件に指定した検索を行うこともできる。

`n per page'の設定により、結果のページに表示される件数を変えられる。`n level rep' の設定により、URIの階層が同じ結果を最もスコアの高いものに代表させられる。`sort by order' の設定により、検索結果の並び順を指定できる。

正規表現の機能を有効にしてEstraierをビルドした場合、検索語の表現形式を選択することができる。`as-is expression' だと指定した語そのものを表現する。`with wild cards' は語の中にワイルドカードとして `*' を含めることができる。ワイルドカードはいかなる文字列にもあてはまる。`regular expression' は指定した語を正規表現(POSIX拡張正規表現)として扱う。正規表現の基本的な書式を以下に示す。

P `P' そのものにあてはまる。
PQ `P' と `Q' が連続している文字列にあてはまる。
. いかなる1文字にあてはまる。
P* `P' が0個以上連続している文字列にあてはまる。
P+ `P' が1個以上連続している文字列にあてはまる。
P? 0個か1個の `P' にあてはまる。
P|Q `P' と `Q' の両方にあてはまる。
^P 先頭にある `P' にあてはまる。
P$ 末尾にある `P' にあてはまる。
(P) `P' の中の評価を優先させる。

例えば、`work' で始まる語(`work'、`worked'、`worker'、`works' など)を表現するには、ワイルドカードを使って `work*' とするか、正規表現を使って `^work.*' とすればよい。

ワイルドカードや正規表現は演算子と併用することもできる。例えば、`apple' か `orange' を含み、かつ `grape' か `melon' を含み、しかし `kiwi' や `banana' は含まないという条件は、正規表現を用いて以下のように表現する。

^(apple|orange)$ [and] ^(grape|melon)$ [not] ^(kiwi|banana)$

正規表現は、カタカナ語の表記のゆれを吸収するのにも役に立つ。例えば、「プロクシ」「プロキシ」「プロクシー」「プロキシー」のどれかを含み、かつ「サーバ」「サーバー」のどちらかを含む文書を検索するには、以下のようにする。

^プロ(ク|キ)シ(ー)?$ ^サーバ(ー)?$

ワイルドカードや正規表現によって展開される語の候補の最大数は1024個である。

検索結果

検索結果には、検索条件に該当する文書とその要約や属性が表示される。要約の欄にはキーワードのリストも表示される。キーワードを選択すると、現在の検索条件にそのキーワードのAND条件を加えて再検索を行う。検索結果を絞り込んでいく際にこの機能は便利である。要約は検索語がハイライトされて表示されるので、検索語の使われ方を確認しやすい。

要約の欄の `(detail)' を選択すると、要約用に登録されている単語のリストが表示される。要約と同じく検索語がハイライトされるので、文書内で検索語の場所を探すのに便利である。

要約の欄の `(related)' を選択すると、その文書を元として関連文書検索を行う。関連文書検索は、単語の出現傾向が近い文書を提示する機能である。検索語の選択がうまくできない場合でも、文書の関連をたどっていけば目的の文書を捜し出せるかもしれない。

指定した表示件数よりも該当の文書数が多い場合は、複数のページに分けて提示される。ページの下端にある `PREV' や `NEXT' を選択することで、ページを戻したり進めたりすることができる。

検索結果が非常に多い場合は、その全ての適合性を判定せずに検索結果を提示することがある。その際にはページの上端に `(or more)' というリンクが表示されるので、それを選択すると完全な結果を得ることができる。

設置

検索用のCGIスクリプト `estsearch.cgi' は `/usr/local/libexec/estsearch.cgi' としてインストールされているので、それをWebで公開するディレクトリにコピーする。通常、同じ場所に転置インデックスや各種設定ファイルも置くことになる。

設定ファイルは、`estsearch.conf'、`estsearch.tmpl'、`estsearch.top' の三つである。それらのデフォルトの記述が `/usr/local/share/estraier' の下にインストールされているので、それをコピーしてカスタマイズするとよい。

検索設定ファイルは、`estsearch.cgi' のプロセスにとってのカレントディレクトリに置いてある必要がある。多くの場合、CGIスクリプトのあるディレクトリがカレントディレクトリになるが、Webサーバの実装によっては異なる場合もある。Microsoft IISでは、「仮想ディレクトリ」のルートがCGIスクリプトのカレントディレクトリになるので注意が必要である。

検索設定ファイル

`estsearch.cgi' は、そのカレントディレクトリにある `estsearch.conf' という名前のファイルから設定を読み込む。設定ファイルの各行には、行頭に属性名、その後ろに `:'、その後ろに属性値という形式をとる。検索設定ファイルの文字コードはUS-ASCIIかUTF-8とする。代表的な設定内容を以下に示す。

indexname: casket
tmplfile: estsearch.tmpl
topfile: estsearch.top
prefix: ./
suffix:
replace:
diridx: index.html
decuri: false
boolunit: 1024
relkeys: 16
defmax: 8
reevmax: 1024
showkeys: 8
sumall: 96
sumtop: 24
sumwidth: 16
logfile:

`indexname' は転置インデックスの名前を指定する。別の名前を使いたい場合や、カレントディレクトリ以外の場所に置きたい場合は、これを変更する。`tmplfile' は後述するテンプレートファイルの名前を指定する。`topfile' は後述するトップページファイルを指定する。これらも別の名前にしたい場合に変更する。`prefix' は検索結果の各文書のURIの先頭に付加する文字列を指定する。例えば、`http://foo.bar/baz/' とすると、`./apple.html' は `http://foo.bar/baz/apple.html' として表示される。`suffix' は各文書のURIの末尾に付加する文字列を指定する。例えば、`.html' とすると、`./data/751' は `./data/751.html' になる。`replace' は各文書のURIに対する置換表現を指定する。置換前の文字列と置換後の文字列を空白で区切って指定する。例えば、`/foo/ /bar/' とすると、`./foo/apple.html' は `./bar/apple.html' に置換される。この項目は複数置くことができる。`diridx' はディレクトリのインデックスファイルを指定する。例えば `index.html' の場合、`./foo/index.html' は `./foo/' として表示される。`decuri' が `true' の場合、検索結果のURIをURLエンコードされたものとみなし、それをデコードする。これはGNUの `wget' コマンドで保存したファイルを扱う際に有用である。`boolunit' と `relkeys' は通常検索と関連文書検索の精度を決めるパラメータである。これらを大きくすると精度が向上するが処理速度は下がる。これらを小さくすると精度は下がるが処理速度は向上する。通常、これらを変更する必要はない。`defmax' は、検索結果の表示件数のデフォルト値を指定する。`reevmax' は正規表現を展開する最大語数を指定する。`showkeys' は検索結果で表示されるキーワードの数を指定する。`sumall' は要約の語数を指定する。`sumtop' は文書の冒頭から要約に入れる語数を指定する。`sumwidth' は要約において検索語の前後から抽出する語数を指定する。`logfile' は入力された検索条件のログを出力するファイルを指定する。この他に、表示される文字列を指定する属性が20個ほどある。

テンプレートファイル

テンプレートファイルは、検索画面でユーザに提示されるHTMLのテンプレートを指定する。いわゆるスキンのような機能を提供する。このファイルは通常 `estsearch.tmpl' という名前だが、検索設定ファイルによって別の名前にすることもできる。このファイルを編集して、ユーザインタフェースを自由にカスタマイズすることができる。テンプレートファイルの文字コードはUS-ASCIIかUTF-8とする。ほとんどの内容はユーザインタフェースにそのまま反映されるが、以下の置換が行われる。

<!--ESTFORM-->
検索条件を入力するフォームを表示する。
<!--ESTRESULT-->
検索結果を表示する
<!--ESTINFO-->
転置インデックスに登録された文書数と語数を表示する。
<!--ESTPROCTIME-->
検索処理にかかったCPU時間を表示する。
<!--ESTVERSION-->
Estraierのバージョン情報を表示する。
<!--ESTFILE:name-->
`name' で指定したファイルの内容を表示する。
<!--ESTEXEC:command-->
`command' で指定したコマンドをシェルで実行し、その結果を表示する。
{ESTPHRASE}
ユーザが入力した検索フレーズを表示する。
{ESTMAX}
ユーザが指定した結果表示件数を表示する。
{ESTDNUM}
転置インデックスに登録された文書数を表示する。
{ESTWNUM}
転置インデックスに登録された語数を表示する。

`<!--ESTEXEC:command-->' の機能を利用すると、HTMLをページに動的に挿入することができる。いわゆるプラグインのような機能である。呼び出したコマンドには、環境変数 `ESTPHRASE' の値として `phrase' パラメータの値が渡される。それ以外のパラメータは環境変数 `QUERY_STRING' の値を解析して取得することができる。

トップページファイル

トップページファイルは、ユーザが検索条件を入力していない時に検索結果として表示されるメッセージを指定するファイルである。すなわち、ユーザが `estsearch.cgi' を最初に訪れた際に提示されるべき情報を記述する。このファイルは通常 `estsearch.top' という名前だが、検索設定ファイルによって別の名前にすることもできる。このデータは `<!--ESTRESULT-->' の場所にそのまま挿入されるので、HTMLの断片として記述する。トップページファイルの文字コードはUS-ASCIIかUTF-8とする。

テンプレートファイルやトップページファイルを編集するにあたり、Estraierのロゴやバージョン情報を残す必要はない。ユーザの好みに応じたデザインにすべきである。ただし、ページが表示される際にHTML(XHTML)として妥当な形式になるように努めるべきである。トップページファイルには、ユーザの理解できる言語で簡単なヘルプを記述しておくことが推奨される。日本語の設定ファイルのサンプルが `/usr/local/share/estraier/locale/ja' にインストールされるので、それをカスタマイズするとよい。

ログファイル

検索設定ファイルで `logfile' を指定した場合、ユーザが入力した検索条件をログファイルに出力する。各々の検索条件は改行で区切られ、その中にタブで区切られた以下の項目が記録される。

検索フォーム

別のページに検索フォームを置きたい場合は、以下のようなHTMLを書けばよい。`phrase' パラメータは検索フレーズを指定する。`enc' パラメータは検索フォームを設置するページの文字コードを指定する。

<form method="get" action="estsearch.cgi">
<div>
<input type="text" name="phrase" value="" size="64" tabindex="1" />
<input type="submit" value="Search" tabindex="2" />
<input type="hidden" name="enc" value="UTF-8" />
</div>
</form>

検索サーバ

`estsearch.cgi' はCGIスクリプトであるため、アクセスされる度にデータベースや形態素解析器と接続するオーバーヘッドがかかる。この問題を解決すべく、Estraierには `estserver' コマンドが付属する。これは、Webサーバに全文検索の機能を持たせたものである。用法は以下である。カレントディレクトリ以下のファイルをWebを介して公開するとともに、`/estsearch' というURLが要求された際には、`estsearch.cgi' と全く同じインタフェースの検索機能を提供する。引数が指定されなかった場合、転置インデックスとして `casket'、設定ファイルとして `estsearch.conf'、テンプレートファイルとして `estsearch.tmpl'、トップページファイルとして `estsearch.top' を読み込む。

estserver [-host name] [-port num] [-div num] [-uid num] [index conffile tmplfile topfile]
`index' は `estindex' コマンドで作成した転置インデックスを指定する。
`conffile' は `estsearch.cgi' と共通の設定ファイルを指定する。
`tmplfile' は `estsearch.cgi' と共通のテンプレートファイルを指定する。
`topfile' は `estsearch.cgi' と共通のトップページファイルを指定する。
`-host name' はサーバのホスト名を指定する。デフォルトでは、サーバは全てのネットワークインタフェースにバインドされ、システムの正式名称をホスト名とする。
`-port num' はサーバのポート番号を指定する。デフォルトは 4210 である。
`-div num' は子プロセスの数を指定する。デフォルトは 4 である。
`-uid num' は子プロセスのユーザIDを指定する。デフォルトは親と同じである。このオプションは親プロセスの実行者がスーパーユーザの場合にのみ機能する。

例えば、ホスト名 `estraier.foo.edu' の 8888 番ポートで `/home/mikio/public_html' 以下のコンテンツを公開する場合、そこに転置インデックスと各種設定ファイルを設置した上で、以下のコマンドを実行する。そして、`http://estraier.foo.edu:8888/estsearch' にアクセスする。

cd /home/mikio/public_html
estserver -host estraier.foo.edu -port 8888 \
  casket estsearch.conf estsearch.tmpl estsearch.top

サポートされるメソッドはGETとPOSTとHEADである。CGIはサポートされない。検索設定ファイルにおいて、`indexname' と `tmplfile' と `topfile' は無視される。ログメッセージは標準出力に出力される。

このコマンドのプロセスはひとつの親プロセスと複数の子プロセスからなる。クライアントからのリクエストを処理するのは子プロセスの仕事である。各々の子プロセスは 64 回のリクエストを処理したら終了する。親プロセスは子プロセスの終了が終了すると即座に代替の子プロセスを生成する。この機構によって安全な並列処理が実現される。サービスを停止させるには、SIGINTシグナル(Control-C)を親プロセスに送ればよい。待機プロセス(子プロセス)の数を 0 にすると、親プロセス自体がリクエストを処理するようになる。

パラメータ

`estsearch.cgi' と `estserver' は以下のパラメータを受け付ける。各パラメータの値は通常のCGIスクリプトと同様にURLエンコードされている必要がある。

検索コマンド

シェルや各種のスクリプト言語から検索を行うために、コマンド `estxview' が提供される。このコマンドは検索結果をXMLとして標準出力に出力する。それを加工することで、独自のユーザインタフェースを実現することができる。用法は以下である。デフォルトでは、検索条件を `estsearch.cgi' と互換の検索フレーズとして解釈して検索を行う。引数の文字コードはUTF-8である必要がある。`-relsc' オプションのスコア表現はTSV形式で、各行には語とスコア値のペアをとる。

estxview [-id] [-uri] [-rel] [-relsc] [-expr type] [-sort type] [-drep num] [-max num] [-ni] [-tiny] [-nt] [-snum num] [-nk] [-css] [-xsl] [-dtd] [-rf] [-dlist] [-wlist] name [expression...]
`name' は転置インデックスの名前を指定する。
`expression' は検索条件を指定する。
`-id' が指定されると検索式をIDに持つ文書を検索する。
`-uri' が指定されると検索式をURIに持つ文書を検索する。
`-rel' が指定されると検索式をIDに持つ文書を種文書として関連文書検索を行う。
`-relsc' が指定されると検索式のスコア表現を種文書として関連文書検索を行う。
`-expr' は検索語の表現形式を指定する。`type' は `asis'、`wild'、`regex' のどれか。デフォルトは完全一致表現。
`-sort' は検索結果の並び順を指定する。`type' は `score'、`r-score'、`date'、`r-date'のどれか。デフォルトはスコア順。
`-drep' は階層結合のレベルを指定する。デフォルトは結合なし。
`-max' は表示文書数を指定する。デフォルトは 8 である。
`-ni' が指定されるとTF-IDF法を無効にする。デフォルトは有効である。
`-tiny' が指定されると文書のIDとスコアのみを出力する。
`-nt' が指定されると該当文書のテキストを表示しない。
`-snum' は要約に含まれる語数を指定する。デフォルトは 80 である。
`-nk' が指定されると該当文書のキーワードを表示しない。
`-css' が指定されると `estxview.css' を参照する処理命令を埋め込む。
`-xsl' が指定されると `estxview.xsl' を参照する処理命令を埋め込む。
`-dtd' が指定されると `estxview.dtd' を参照する文書型宣言を埋め込む。
`-rf' が指定されると検索条件を `expression' で指定したファイルから読み込む。
`-dlist' が指定されると全ての登録文書の情報を出力する。
`-wlist' が指定されると全ての索引語の情報を出力する。

このコマンドは、検索が成功した場合には 0 を返し、一度でもエラーが起きた場合は 1 を返す。出力の書式と意味については `estxview.dtd' を参照すること

スコアリングのアルゴリズム

検索の際に表示されるスコアは、以下に示すアルゴリズムによって算出される。

関連文書検索の際に表示される類似度は、以下に示すアルゴリズムによって算出される。


メタ検索システム

概要

Estraierが一つの転置インデックスに登録できる文書の数は、各文書のサイズにもよるが、現実的には100万件程度が限界である。より大規模な検索システムを構築する場合、転置インデックスを複数台のコンピュータに分散させて配置する必要がある。検索時には、各々のコンピュータに一斉に問い合わせを発行し、その結果をマージするエージェントを利用することになる。`estmerge.cgi' はそのためのプログラムである。

`estmerge.cgi' は、`estsearch.cgi' や `estserver' を対象としたメタ検索ができるだけでなく、`estmerge.cgi' を再帰的に検索対象とすることもできる。メタ検索を多階層で行うことによって、非常に大規模な検索システムを構築することができる。例えば、始めに10サイトに対してクエリを発行し、その10サイトが各々10サイトにクエリを発行すれば、100サイトを対象にした検索が実現できる。

設置

メタ検索用のCGIスクリプト `estmerge.cgi' は `/usr/local/libexec/estmerge.cgi' としてインストールされているので、それをWebで公開するディレクトリにコピーする。検索対象は同じコンピュータ上にあってもそうでなくてもよい。

設定ファイルは、`estmerge.conf'、`estmerge.tmpl'、`estmerge.top' の三つである。それらのデフォルトの記述が `/usr/local/share/estraier' の下にインストールされているので、それをコピーしてカスタマイズするとよい。

検索設定ファイルは、`estmerge.cgi' のプロセスにとってのカレントディレクトリに置いてある必要がある。多くの場合、CGIスクリプトのあるディレクトリがカレントディレクトリになるが、 Webサーバの実装によっては異なる場合もある。

検索設定ファイル

`estmerge.cgi' は、そのカレントディレクトリにある `estmerge.conf' という名前のファイルから設定を読み込む。設定ファイルの各行には、行頭に属性名、その後ろに `:'、その後ろに属性値という形式をとる。検索設定ファイルの文字コードはUS-ASCIIかUTF-8とする。代表的な設定内容を以下に示す。

target: Foo@http://www.foofoo.go.jp/foo/estsearch.cgi
target: Bar@http://www.barbar.ad.jp/bar/estsearch.cgi
target: Baz@http://www.bazbaz.ac.jp/baz/estsearch.cgi
proxy: proxy.mydomain.gov:3128
tmplfile: estmerge.tmpl
topfile: estmerge.top
hidetl: false
defmax: 8
logfile:

`target' は検索対象を指定する。対象のラベルとURLを `@' で区切って指定する。この項目は複数置くことができる。`proxy' はHTTPのプロクシを指定する。プロクシのホスト名とポート番号を `:' で区切って指定する。プロクシを利用しない場合は値を空にすればよい。`tmplfile' は後述するテンプレートファイルの名前を指定する。`topfile' は後述するトップページファイルを指定する。`hidetl' が `true' の場合、検索対象のラベルが隠される。`defmax' は、検索結果の表示件数のデフォルト値を指定する。`logfile' は入力された検索条件のログを出力するファイルを指定する。この他に、表示される文字列を指定する属性が20個ほどある。

テンプレートファイル

テンプレートファイルは、検索画面でユーザに提示されるHTMLのテンプレートを指定する。このファイルは通常 `estmerge.tmpl' という名前だが、検索設定ファイルによって別の名前にすることもできる。このファイルを編集して、ユーザインタフェースを自由にカスタマイズすることができる。テンプレートファイルの文字コードはUS-ASCIIかUTF-8とする。ほとんどの内容はユーザインタフェースにそのまま反映されるが、以下の置換が行われる。

<!--ESTFORM-->
検索条件を入力するフォームを表示する。
<!--ESTRESULT-->
検索結果を表示する
<!--ESTVERSION-->
Estraierのバージョン情報を表示する。
<!--ESTFILE:name-->
`name' で指定したファイルの内容を表示する。
<!--ESTEXEC:command-->
`command' で指定したコマンドをシェルで実行し、その結果を表示する。
{ESTPHRASE}
ユーザが入力した検索フレーズを表示する。
{ESTMAX}
ユーザが指定した結果表示件数を表示する。

トップページファイル

トップページファイルは、ユーザが検索条件を入力していない時に検索結果として表示されるメッセージを指定するファイルである。すなわち、ユーザが `estmerge.cgi' を最初に訪れた際に提示されるべき情報を記述する。このファイルは通常 `estmerge.top' という名前だが、検索設定ファイルによって別の名前にすることもできる。このデータは `<!--ESTRESULT-->' の場所にそのまま挿入されるので、HTMLの断片として記述する。トップページファイルの文字コードはUS-ASCIIかUTF-8とする。


助言

大規模なインデックスの構築

大規模なサイトの全文検索システムを構築する場合、最初に転置インデックスを作るのにかなりの時間がかかる。登録文書数が数万件に上ると、処理速度が低下し始めるからである。システムが1GB以上のメモリを搭載している場合、`estindex register' コマンドに `-plute' オプションをつけると、転置インデックスをより高速に構築することができる。

数万件ごとに分けて転置インデックスを作成してから、それらをマージする方法もある。この作業を単純化するために、`estautoreg' というコマンドを利用すると便利である。対象文書を収めたディレクトリをカレントディレクトリにして、このコマンドを実行してほしい。すると、転置インデックスとCGIスクリプトの設置が自動的に行われる。第1引数で各要素インデックスの文書数を指定することもできる。

cd /home/mikio/public_html
estautoreg

`estautoreg' は単純なシェルスクリプトなので、好きなように書き換えて利用してほしい。デフォルトでは、各要素インデックスの文書数は 32768 で、要約用の単語数は 4096 である。

転置インデックスの構築を高速に行うためには、システムが潤沢なRAMを搭載していることが望ましい。1万文書あたり20MBが目安である。例えば、対象文書数が100万の場合、2GBのRAMを搭載していることが望ましい。また、I/Oバッファの同期の頻度を少なくするようにシステムをチューニングしておくとよい。例えば、Linuxの場合、`/etc/sysctl.conf' というファイルに以下の行を書き加えるとよい。各々のパラメータの意味は `update -d' を実行すると分かる。

vm.bdflush = 80 1000 0 0 0 10000 100 0 0

システムに搭載されたRAMの容量が転置インデックスのサイズより大きい場合、RAMディスクを使うことによって、とても高速に転置インデックスを構築することができる。Linuxの場合、以下のような手順で転置インデックスを構築するとよい。作業は `root' ユーザで行う。

mkdir -p /mnt/ram
mount -t tmpfs -o size=512m /dev/shm /mnt/ram
cd /home/mikio/public_html
estindex register /mnt/ram/casket
estindex relate /mnt/ram/casket
rm -rf casket
cp -r /mnt/ram/casket .
umount /mnt/ram
rmdir /mnt/ram

RAMディスクでなくハードディスクを使う場合でも、登録対象のファイルがあるディスクとは別のディスク上で転置インデックスを作成する方が、処理が高速である。複数の転置インデックスをマージする際にも、要素となる転置インデックスと作成する転置インデックスのディスクは異なる方が、処理が高速である。

可用性の確保

可用性を高めるためには、転置インデックスを二重化して運用することが推奨される。転置インデックスの更新を行ってる間は、検索を行うことができないからである。また、システムが不意にシャットダウンしたり、ディスクが一杯になったなどの理由で、転置インデックスが更新中に壊れることも考えられる。そこで、以下の手順で更新操作を行うとよい。これをUNIXの `crond' を用いて定期的に実行するようにすると便利である。

cd /home/mikio/public_html &&     # カレントディレクトリを移動する
test -d casket &&                 # 転置インデックスの存在を確認する
test ! -d casket-tmp &&           # 複製が存在しないことを確認する
cp -r casket casket-tmp &&        # 複製を作成する
estindex purge casket-tmp &&      # 複製に削除文書を反映させる
estindex register casket-tmp &&   # 複製に新規文書と更新文書を反映させる
estindex optimize casket-tmp &&   # 複製を最適化する
estindex relate casket-tmp &&     # 複製に関連情報を反映させる
rm -rf casket &&                  # 既存の転置インデックスを削除する
mv casket-tmp casket              # 複製を正規のものに置き換える

実際には、`purge' と `optimize' はそれほど頻繁に実行する必要はないだろう。`register' は毎晩、`relate' は毎週、`purge' と `optimize' は毎月実行するといった運用も考えられる。

共用のレンタルサーバやサービスプロバイダが提供するWebサーバのシステムでEstraierを運用する場合、更新操作によってシステムに高い負荷がかかって他の利用者に迷惑をかけることが考えられる。そのような場合、自分のローカルシステムで転置インデックスを作成し、それをWebサーバのシステムにアップロードすればよい。ただし、この方法はバイトオーダの異なるシステム間では使えない。

リモートサイトの検索

リモートサイトのコンテンツを `wget' で取得してから転置インデックスを作成すれば、リモートサイトの全文検索システムを構築することができる。例えば `http://estraier.foo.edu/' と `http://snatcher.foo.edu/' を対象とする場合、以下の手順を実行すればよい。

cd /home/mikio/public_html
wget -r -N -np -l inf -A ".txt,.TXT,.html,.HTML,.htm,.HTM" "http://estraier.foo.edu/"
wget -r -N -np -l inf -A ".txt,.TXT,.html,.HTML,.htm,.HTM" "http://snatcher.foo.edu/"
estindex register casket
estindex relate casket
cp /usr/local/libexec/estsearch.cgi /usr/local/share/estraier/estsearch.* .

`estsearch.conf' の `prefix' の値は `http://' とし、`decuri' の値は `true' にする。そうすると、検索結果のリンクをたどった際に、ローカルにキャッシュされたコンテンツでなく、オリジナルのサイトにユーザを誘導することができる。

メールボックスの検索

`mh' に似た形式でメールボックスを管理する電子メールクライアント(SylpeedやMewなど)を利用している場合は、そのメールボックスを対象とした全文検索システムを構築することができる。例えばフォルダ `business' と `friends' に振り分けたメールを対象とする場合、以下の手順を実行すればよい。

cd /home/mikio/public_html
ln -s /home/mikio/Mail/inbox .
estindex register -msuf "*" casket ./inbox/business
estindex register -msuf "*" casket ./inbox/friends
estindex relate casket
cp /usr/local/libexec/estsearch.cgi /usr/local/share/estraier/estsearch.* .

その他の形式でメールボックスを管理するクライアント(BeckyやOutlook Expressなど)を利用している場合は、mh形式(eml形式)のファイルをエクスポートしてから、それらを対象として転置インデックスを作成すればよい。なお、mboxの形式でメールボックスを管理するクライアント(EudoraやThunderbirdなど)のメールボックスからmh形式のファイルを作成するには、`estmbtomh' コマンドを用いるとよい。書式は以下である。

estmbtomh [-pre str] [-suf str] [-col num] [file]
`file' はmbox形式のファイルを指定する。省略すると標準入力を読み込む。
`-pre' オプションは出力ファイルの接頭辞として `str' を指定する。
`-suf' オプションは出力ファイルの接尾辞として `str' を指定する。
`-col' オプションは出力ファイルの桁数を `num' に指定する。

個人的なメールをWebで公開するのは危険なので、許可されたユーザのみがアクセスできるようにWebサーバの設定を行うべきである。`Mail' ディレクトリのパーミッションの設定も工夫してみてほしい。MIMEをWebで送信する際の `Content-Type' の値は `message/rfc822' にすべきである。

UIの簡単なカスタマイズ

検索設定ファイルでのUIのカスタマイズでは不十分な場合でも、テンプレートファイルでCSSやJavaScriptを用いると大抵の目的は達成できる。例えば、検索フレーズの入力欄の幅を狭めるためには、CSSの定義部分に以下のように書くだけでよい。

#phrase { width: 32ex; }

検索条件の入力フォームにある `max'、`drep'、`sort'、`expr' の入力欄を消したいならば、以下のように書けばよい。入力欄を個別に消す場合は、IDが `maxspan'、`drepspan'、`sortspan'、`exprspan' の要素のスタイルを `display: none;' にすればよい。

#advancedform { display: none; }

JavaScriptを用いる場合は、HTMLの `body' 要素に `onload' 属性をつけて、ページが描画される際に関数を呼び出すようにする。

<body onload="startup();">

そして、`head' 要素の中に `script' 要素を定義して、その関数を定義する。例えば、検索フレーズの入力欄の幅を狭めたい場合は、以下のようにする。

<script type="text/javascript">
function startup(){
  document.getElementById('phrase').setAttribute('size', '32');
}
</script>

CSSやJavaScriptの能力を越えたカスタマイズをしたい場合は、`estsearch.cgi' を呼び出すラッパスクリプトを作るとよい。CGIのパラメータは環境変数として渡されるので、ラッパの子プロセスとして元のスクリプトを呼び出しても同じ入力を与えることができる。そしてその出力を `awk' や `perl' などのスクリプトで加工するとよい。例えば、以下のラッパスクリプトは検索フレーズの入力欄の幅を狭める。

#! /bin/sh

./estsearch.cgi | awk '
{
  if(match($0, /^<input.*id="phrase"/)){
    sub(/size="[0-9]*"/, "size=\"6\"", $0)
  }
  printf("%s\n", $0)
}
'

リンク先の処理

通常は、検索結果として提示される各該当文書のタイトルを選択することで、ユーザはその文書のURIに誘導される。このようなデフォルトの動作でなく、そのURIに対する任意の処理を行わせることもできる。検索設定ファイルの `altfunc' の値として、その処理を行うクライアントサイドスクリプトの関数名を指定すればよい。タイトルが選択された際には、その関数が呼び出される。第1引数としてその文書のIDが渡される。例えば、リンク先の文書をポップアップウィンドウに表示したい場合、`altfunc' の値を `popup' にし、以下のような記述をテンプレートファイルの `head' セクションに加えればよい。

<script type="text/javascript">
function popup(id){
  var uri = document.getElementById("uri-" + id).href;
  window.open(uri, "_blank", "width=640,height=480,scrollbars=yes");
}
</script>

検索設定ファイルの `prefix' の値として、リンク先の文書に対する処理を行うCGIスクリプトを指定することもできる。例えば、`http://foo.bar/baz.cgi/' とした場合、`./fruits/apple.html' は `http://foo.bar/baz.cgi/fruits/apple.html' となる。すると、`baz.cgi' のプロセスは環境変数 `PATH_INFO' の値として `/fruits/apple.html' を取得できる。

フィルタ用のダイナミックリンクライブラリ

テキスト抽出用のフィルタを関数として呼び出す場合、その関数を実装したダイナミックリンクライブラリを予め作成しておく必要がある。関数のシグネチャは以下である。`infile' は入力ファイル名を指示し、`outfile' は出力ファイル名を指示する。また、環境変数 `ESTORIG' で元来のファイル名が指示される。この関数は入力ファイルを読み込み、テキストを抽出し、HTMLとして出力ファイルに書き込むという機能を持つことが期待される。

void estfilter(const char *infile, const char *outfile);

例えば、プレーンテキストをHTMLに加工する関数は以下のように定義する。

#include <stdio.h>

void estfilter(const char *infile, const char *outfile){
  FILE *IN, *OUT;
  int c;
  if((IN = fopen(infile, "rb")) != NULL){
    if((OUT = fopen(outfile, "wb")) != NULL){
      fprintf(OUT, "<html><body><pre>");
      while((c = fgetc(IN)) != EOF){
        switch(c){
        case '&': fprintf(OUT, "&amp;"); break;
        case '<': fprintf(OUT, "&lt;"); break;
        case '>': fprintf(OUT, "&gt;"); break;
        default: fputc(c, OUT); break;
        }
      }
      fclose(OUT);
      fprintf(OUT, "</pre></body></html>");
    }
    fclose(IN);
  }
}

上記を `filtertest.c' というファイルとし、`libfiltertest.so' を作成するには、以下のコマンドを用いる(GCCとGNU Linkerを用いる場合)。

gcc -c -fPIC filtertest.c
ld -shared -o libfiltertest.so filtertest.o -lc

上記で作成した `libfiltertest.so' をフィルタとして利用して転置インデックスを作成するには、以下のコマンドを用いる。

estindex register -tsuf "" -hsuf "" -msuf "" \
  -xsuf .txt text/plain @libfiltertest.so casket

Estraierのプロセスがダイナミックリンクライブラリを検索するためには、環境変数 `LD_LIBRARY_PATH' の値に対象のライブラリを配置したディレクトリを含めることが必要である。

テキスト解析オプションの比較

テキスト解析の汎用オプションによる振る舞いの比較を以下に示す。入力文は、「"Don't despair; your ideal lover is waiting for you."」とする。

オプション 正規形(検索語) 出現形
なし despair ideal lover waiting " Don ' t despair; your ideal lover is waiting for you. "
strict despair ideal lover waiting "Don't despair; your ideal lover is waiting for you."
no-stopword don t despair your ideal lover is waiting for you " Don ' t despair; your ideal lover is waiting for you. "
no-stopwordとstrict don't despair your ideal lover is waiting for you "Don't despair; your ideal lover is waiting for you."

和文解析用のオプションによる振る舞いの比較を以下に示す。入力文は、「今日はライブではしゃいで楽しかった。」とする。

モジュール 正規形(検索語) 出現形
デフォルト 今日 ライブ 楽 今日 は ライブ ではしゃいで 楽 しかった 。
Chasen 今日 ライブ はしゃぐ 楽しい 今日 は ライブ で はしゃい で 楽しかっ た 。
Kakasi 今日は ライブ ではしゃいで 楽し かった 今日は ライブ ではしゃいで 楽し かった 。

ChasenやKakasiを使っている場合に、辞書に登録されていない単語で検索を行おうとするとうまく検索できないことがある。この問題に対処するには、辞書を強化するしかない。辞書を変更した場合は転置インデックスも作りなおす必要がある。

転置インデックスの形式

転置インデックスはデータベースライブラリQDBMによって管理される。その中心となるのは転置インデックス用のOdeumというAPIである。Odeumはディレクトリの中に複数のファイルやサブディレクトリを作り、その中でデータを管理する。その他にもQDBMの他のAPI(DepotとCuriaとCabinとVilla)によるファイルがいくつか作られる。それらの構成を以下に示す。

Estraierの機能を拡張する際には、上記以外のデータベースを転置インデックスのディレクトリに作成することができる。ユーザ独自の文書属性を記録したいならば、文書IDをキーとし、属性値を値にするとよい。文書属性を条件として検索を行いたいならば、属性値を検索キーとし、文書IDの配列を値にするとよい。

管理者権限がない場合のインストール

学校や会社のコンピュータ、もしくはISPのレンタルサーバを使っている場合、管理者権限がないことも多いだろう。しかし、Estraierや関連するライブラリ群を自分のホームディレクトリにインストールして動作させることもできる。以下の例では、Chasenを有効化したEstraierをインストールしている。`gzip'、`tar'、`gcc'、`make' は既にインストールしてあるものとする。

# ビルド環境の設定
cd
mkdir -p bin lib include etc share libexec
PATH=$HOME/bin:$PATH
LIBRARY_PATH=$HOME/lib:$LIBRARY_PATH
CPATH=$HOME/include:$CPATH
LD_LIBRARY_PATH=$HOME/lib:$LD_LIBRARY_PATH
export PATH LIBRARY_PATH CPATH LD_LIBRARY_PATH

# zlibのインストール
gzip -cd zlib-1.2.1.tar.gz | tar xvf -
cd zlib-1.2.1
./configure --prefix=$HOME
make
make install
cd

# libiconvのインストール
gzip -cd libiconv-1.9.2.tar.gz | tar xvf -
cd libiconv-1.9.2
./configure --prefix=$HOME
make
make install
cd

# chasenのインストール
gzip -cd chasen-2.2.9.tar.gz | tar xvf -
cd chasen-2.2.9
./configure --prefix=$HOME
make
make install
cd

# ipadicのインストール
gzip -cd ipadic-2.5.1.tar.gz | tar xvf -
cd ipadic-2.5.1
./configure --prefix=$HOME
make
make install
cd

# estraierのインストール
gzip -cd estraier-1.2.8.tar.gz | tar xvf -
cd estraier-1.2.8
./configure --prefix=$HOME
make
make install
cd

通常なら `/usr/local' にインストールされるものが全て自分のホームディレクトリにインストールされる。したがって、利用する際には、環境変数 `PATH' に `$HOME/bin' を含め、環境変数 `LD_LIBRARY_PATH' に `$HOME/lib' を含めること。各種設定ファイルは `$HOME/libexec' や `$HOME/share' の下に置かれる。利用しているコンピュータでWebサーバが動作していなかったり、動作していてもCGIの実行許可がない場合は、`estserver' を使うとよい。

よく聞かれる質問

Q. : EstraierはNamazuとどう違うのですか。
A. : Estraierは多くの点でNamazuの設計を参考にして作られています。Namazuの主な機能はEstraierでも実装されています。一般的なユーザにとってはどちらを使っても遜色ないと思います。強いて言えば、ハイライト機能が格好いいことと、関連文書検索ができることがEstraierの利点でしょう。逆に、Perlプログラマにとってはカスタマイズしやすいことと、各種のアプリケーションが充実していることと、ユーザ数が多いのでサポートが受けやすいことがNamazuの利点でしょう。
Q. : 転置インデックスの更新処理中に検索を行うことはできますか。
A. : できません。転置インデックスの複製に対して更新を行うことで対処してください。
Q. : 意図した検索語が抽出されないのですが。
A. : アルゴリズムの特性上、残念ながらユーザの期待する検索語が抽出できないこともあります。
Q. : ChasenとKakasiのどちらを使えばよいですか。
A. : 日本語の文書を対象にする場合、Chasenを使うことを強く推奨します。
Q. : 何文書くらい扱えますか。
A. : Webから取得した56万件のHTML文書をひとつの転置インデックスに格納したのが、私の試した最大規模です。高速なCPUと大容量のメモリがあると、より多くの文書を扱うことができます。OS(ファイルシステム)をチューニングすることもスケーラビリティの向上に多大な貢献をします。
Q. : 転置インデックスが壊れることはありますか。
A. : 転置インデックスの更新作業の途中でアプリケーションが強制終了されたり、OSがクラッシュした場合に、転置インデックスが壊れることがあります。検索によって転置インデックスが壊れることは決してありません。
Q. : 動作検証はどのようにしていますか。
A. : 毎回のリリースの前に、少なくとも `make check' と `make check-valgrind' と `make check-xml' を実行して、エラーやメモリリークがないことを確認しています。検証環境はLinux 2.4です。
Q. : `estserver' は `estsearch.cgi' に較べてどれくらい速いのですか。
A. : 2倍程度速いです。つまり、検索の応答時間が半分程度になります。
Q. : Estraierを商用で使ってもよいですか。
A. : はい。Estraierの法人利用や商業利用にあたって作者に許可をとる必要はありません。
Q. : 私は文系なので難しくてよくわかりません。
A. : 私も文系ですので大丈夫です。UNIXの基礎的なリテラシを持ち、Webサーバの管理方法を理解していれば、Estraierも使いこなせると思います。それらに不慣れな場合は身近なシステム管理者に相談してください。それでわからなければ、躊躇せずにEstraierのメーリングリストに質問を出してください。

バグ

「estraier」は、昔のフランス語で「道に迷う」という意味の言葉だそうだが、作者はそれをどう発音すべきか未だに知らない。

Estraierのバージョンが上がる際には、古いバージョンで作成した転置インデックスの互換性は保証されない。したがって、バージョンを上げた際には、転置インデックスを作り直す必要がある。

将来的には、ローカルファイルシステム上のファイルだけでなく、Webから取得したコンテンツを転置インデックスに直接登録する機能を作る予定であるが、現バージョンではできていない。

中国語や朝鮮語の処理が実用的ではない。形態素解析器を入手していないのと、文字コードや言語の自動判定が難しいのがその理由である。

文字コードを自動判定する際に、Shift_JISの機種依存文字が含まれていると誤認識することが多い。また、RFC2822に違反するメールクライアントから送られたメールに対しても、文字コードの誤認識が起こりやすい。そのような文字とソフトウェアはインターネットを介したコミュニケーションにおいて用いるべきではない。

ワイルドカードや正規表現を使った検索は遅い。また、正規表現の国際化(地域化)が不十分である。

バグや不具合を発見したら、是非とも作者にフィードバックしてほしい。その際、Estraierのバージョンと、利用環境のOSとコンパイラのバージョンも教えてほしい。できれば、`./configure' を実行した際に生成される `config.log' を送ってほしい。


ライセンス

Estraierはフリーソフトウェアである。あなたは、Free Software Foundationが公表したGNU General Public Licenseのバージョン2あるいはそれ以降の各バージョンの中からいずれかを選択し、そのバージョンが定める条項に従ってEstraierを再頒布または変更することができる。

Estraierは有用であると思われるが、頒布にあたっては、市場性及び特定目的適合性についての暗黙の保証を含めて、いかなる保証も行なわない。詳細についてはGNU General Public Licenseを読んでほしい。

あなたは、Estraierと一緒にGNU General Public Licenseの写しを受け取っているはずである(`COPYING' ファイルを参照)。そうでない場合は、Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA へ連絡してほしい。

Estraierは平林幹雄が作成した。作者と連絡をとるには、`mikio@users.sourceforge.net' 宛に電子メールを送ってほしい。ただし、質問やバグレポートなど、他のユーザと共有できる話題はメーリングリストに送ってほしい。メーリングリストの参加方法については、`http://lists.sourceforge.net/lists/listinfo/estraier-users-ja' を参照すること。