このガイドでは、Hyper EstraierのWebクローラの詳細な使い方を説明します。ユーザガイドとP2Pガイドをまだお読みでない場合は先にそちらに目を通しておいてください。
estcmd
だとローカルのファイルシステム上にある文書(ファイル)を対象としたインデクシングしかできません。NFSやSMB等を用いてファイルシステムをリモートマウントすれば別のマシンにある文書をインデクシングすることもできますが、不特定対数のWebサイトの文書を扱おうとするとそうもいきません。wget
などのクローラで文書を集めて来てローカルに保存してからインデクシングすることも考えられますが、ディスク容量の問題や更新頻度の問題などがあります。
Web上のリンクを辿って文書を収集することをWebクローリングと言い、そのプログラムをWebクローラと言います。Hyper Estraierに付属のWebクローラestwaver
を使うと、任意のWebサイトの文書を直接的にインデックスに登録することができます。
estwaver
は賢いクローラです。深さ優先探索や幅優先探索のような単純なアルゴリズムでなく、文書の内容を判断して関連するものを優先的に辿って行きます。種文書として指定した文書は、探索の起点になるとともに、類似度判定の材料にもなります。類似検索と同じ要領で種文書のベクトルの和に対する類似度を算出し、それが高い文書のリンク先を優先的に辿ります。
estwaver
も多彩な機能をもっていますが、基本的な使い方は単純です。実際に動かしながら使い方を身につけていきましょう。
クローラを動かす準備として、以下のコマンドを実行してクローラルートディレクトリを作ってください。クローラルートディレクトリとは、クローラの動作に必要な設定ファイルなどを格納するディレクトリツリーのトップのことです。
estwaver init casket
デフォルトではHyper Estraierのホームページなどを起点としてクローリングを行うように設定されています。casket/_conf
を編集すれば、設定を変更することができます。とりあえずはseed
という項目を編集して、巡回の起点となるURLに好きなサイトのURLを指定してください。「|
」の前の部分は類似度判定の重み付けなのですが、とりあえずは「1.0
」にしておけばよいでしょう。なお、プロクシを使わないとWebが見られない環境では、proxyhost
とproxyport
にプロクシのホスト名とポート番号を設定することも必要です。また、日本語のサイトを優先して巡回したい場合はlanguage
を1
にするとよいでしょう。例えば以下のように設定します。
seed: 1.0|http://www.asahi.com/ seed: 1.0|http://www.yomiuri.co.jp/ seed: 1.0|http://www.mainichi.co.jp/ ... proxyhost: proxy.yourdomain.ad.jp proxyport: 8080 ... language: 1 ...
それでは、クローラを動かしてみましょう。以下のコマンドを実行してください。
estwaver crawl casket
すると、文書が続々と取得されてインデックスに登録されていきます。停止させたい場合は端末でCtrl-C
を入力してください。しばらく待つと停止します。
クローリングが終った時には、クローラルートディレクトリの中に_index
というディレクトリができています。これがestcmd
等で利用できるインデックスです。作成されたインデックスを使って検索を行ってみましょう。
estcmd search -vs casket/_index "hyper estraier"
中断したクローリングを再開するには、再びestwaver crawl
を実行します。
estwaver crawl casket
-revisit
オプションをつけてestwaver crawl
を実行すると、既にインデックスに登録した文書のみを対象にして再巡回を行い、更新された文書をインデックスに反映させたり、削除された文書の情報をインデックスから削除したりできます。
estwaver crawl -revisit casket
-revcont
オプションをつけてestwaver crawl
を実行すると、既存の文書の再巡回を行ってから、他の文書のクローリングを続行します。-restart
オプションをつけてestwaver crawl
を実行すると、クローリングを最初からやり直して、Web上で更新された文書の内容をインデックスに反映させることができます。通常の運用では、-revcont
オプションで定期的にインデックスを更新するのがよいでしょう。
企業や学校などのイントラネットでいくつかのWebサイトを運営している場合にもクローラを使ってインデクシングをすると便利です。イントラネットの文書からも外部(インターネット)へのリンクが張ってあることが考えられるので、casket/_conf
のallowrx
を編集して巡回先を制限します。例えば、estraier.ad.jp
ドメインのみを巡回する場合は以下のようにします。
seed: 1.0|http://www.estraier.ad.jp/ seed: 1.0|http://intra.estraier.ad.jp/ ... allowrx: ^http://[^/]*\.estraier.ad.jp/ ...
数百万件以上の文書を対象にしたい場合は、巡回した文書を全て単一のインデックスに登録していくのはスケーラビリティの観点から現実的ではありません。また、クローラが動作している間はインデックスがロックされてしまうという欠点もあります。P2P機構のノードサーバに文書を登録するとその問題を解決できます。それには、casket/_conf
のnodeserv
を編集して、登録先のノードサーバを指定します。例えば、http://foo.estraier.ad.jp:1978/node/node1
とhttp://bar.estraier.ad.jp:1978/node/node2
とhttp://baz.estraier.ad.jp:1978/node/node3
の3つのノードサーバに分散して登録する場合は、以下のようにします。「|
」の前の部分はノードサーバにつけるIDなのですが、各々がユニークになるように適当な番号を指定してください。「admin:admin
」の部分にはノードサーバに接続する際のユーザ情報を指定してください。
nodeserv: 1|http://admin:admin@foo.estraier.ad.jp:1978/node/node1 nodeserv: 2|http://admin:admin@bar.estraier.ad.jp:1978/node/node2 nodeserv: 3|http://admin:admin@baz.estraier.ad.jp:1978/node/node3
複数のノードサーバを指定すると適当な件数毎に分散して登録されるので、検索する際にはノードサーバのメタ検索機能を利用することになります。
ここでは、Web上の文書を対象としたインデックスを作るためのコマンドestwaver
の詳細な仕様を説明します。
estwaver
は多くのサブコマンドの集合体です。サブコマンドの名前は第1引数で指定されます。その他の引数はサブコマンドの種類に応じて解釈されます。rootdirという引数はクローラルートディレクトリです。クローラルートディレクトリとは、クローラの動作に必要な設定ファイルなどを格納するディレクトリツリーのトップのことです。
全てのサブコマンドは、処理が正常に終了した場合には0を、そうでない場合は1を終了ステータスにします。起動中のクローラに1(SIGHUP)、2(SIGINT)、3(SIGQUIT)、15(SIGTERM)のどれかのシグナルを送ることにより、データベースを閉じて正常終了させることができます。
クローラルートディレクトリは以下のファイルやディレクトリを格納しています。
設定ファイルは、変数名と値を「:
」で区切った形式の行を並べたものです。デフォルトでは、設定ファイルは以下のような内容になっています。
seed: 1.5|http://fallabs.com/hyperestraier/uguide-en.html seed: 1.0|http://fallabs.com/hyperestraier/pguide-en.html seed: 1.0|http://fallabs.com/hyperestraier/nguide-en.html seed: 0.0|http://fallabs.com/qdbm/ proxyhost: proxyport: interval: 500 timeout: 30 strategy: 0 inherit: 0.4 seeddepth: 0 maxdepth: 20 masscheck: 500 queuesize: 50000 replace: ^http://127.0.0.1/{{!}}http://localhost/ allowrx: ^http:// denyrx: \.(css|js|csv|tsv|log|md5|crc|conf|ini|inf|lnk|sys|tmp|bak)$ denyrx: \.(zip|tar|tgz|gz|bz2|tbz2|z|lha|lzh)(\?.*)?$ denyrx: ://(localhost|[a-z]*\.localdomain|127\.0\.0\.1)/ noidxrx: /\?[a-z]=[a-z](;|$) urlrule: \.est${{!}}text/x-estraier-draft urlrule: \.(eml|mime|mht|mhtml)${{!}}message/rfc822 typerule: ^text/x-estraier-draft${{!}}[DRAFT] typerule: ^text/plain${{!}}[TEXT] typerule: ^(text/html|application/xhtml+xml)${{!}}[HTML] typerule: ^message/rfc822${{!}}[MIME] language: 0 textlimit: 128 seedkeynum: 256 savekeynum: 32 threadnum: 10 docnum: 10000 period: 10000s revisit: 7d cachesize: 256 #nodeserv: 1|http://admin:admin@localhost:1978/node/node1 #nodeserv: 2|http://admin:admin@localhost:1978/node/node2 #nodeserv: 3|http://admin:admin@localhost:1978/node/node3 logfile: _log loglevel: 2 draftdir: entitydir: postproc:
それぞれの変数の機能を以下に示します。
|
」で区切って指定します。複数回指定できます。[DRAFT]
」とし、プレーンテキスト用なら「[TEXT]
」とし、HTML用なら「[HTML]
」とし、MIME用なら「[MIME]
」とします。複数回指定できます。|
」で区切って指定します。認証情報はホスト名の前に「name:pass@
」の形式で記述します。複数回指定できます。allowrx
とdenyrx
とnoidxrx
は記述した順番に解釈されます。また、正規表現における英字の大文字と小文字は区別されません。
設定ファイルのstrategy
という項目では、リンクを巡回する際の戦略を指定することができます。バランス戦略、深さ優先戦略、幅優先戦略、類似度優先戦略から選ぶことができます。
バランス戦略では、Webクローラとして最も適切であろうという振舞いをします。類似度優先をベースに、多数のサイトから種文書の内容に近い文書を効率良く集められるように調整をします。ブログ等のサイト内リンクに捕らわれて同じような文書ばかり集めたり特定のサイトに高いに負荷を与えたりしないように、他のサイトへのリンクに移動しやすいようにします。類似度優先戦略は、そのような調整をしないで類似度のみで巡回先を決定します。
深さ優先戦略と幅優先戦略は、一般的なツリー構造の探索アルゴリズムとしての深さ優先探索や幅優先探索とほぼ同じ振舞いをします。深さ優先はメモリ使用量を抑えられるという利点がありますが、ブログ等のサイト内リンクに捕らわれる可能性が高いので、不特定多数のサイトを巡回する用途には向きません。幅優先探索は多様なサイトから文書を集められるという利点がありますが、巡回する範囲があまりに広くなるので、これも不特定多数のサイトを巡回する用途には向きません。無作為戦略は巡回先の優先度を無作為に決定するので特定のサイトに負荷が集中しにくいという利点がありますが、幅優先探索と同じ欠点があります。なお、マルチスレッドで動くので、深さ優先戦略は完全な深さ優先探索にはならず、スレッド数の分だけ幅が出て来ます。完全な深さ優先探索をしたい場合はスレッド数を1にしてください。
特定のサイトの文書を全て集めるならば、どの戦略を使っても結果は同じです。とはいえ、メモリ使用量を抑えたいならば深さ優先戦略を使い、ブログ等のWebアプリケーションがある場合に備えるならば幅優先戦略か無作為戦略を使うとよいでしょう。
あるサイトに関連する文書を集めたい場合に、そのサイトの全てのページを指定するのが面倒な場合は、設定ファイルのseeddepth
の値を増やすと便利です。seed
に指定したURLからの指定したホップ数以内で到達できる文書が全て種文書になります。
typerule
では、「{{!}}
」の後に任意のフィルタプログラムのコマンドを書くことができます。フィルタプログラムの仕様はestcmd gather
の「-fx
」オプションと同じで、第1引数に対象文書のパス、第2引数に出力先のパスが渡されて呼び出されます。例えばPDF文書を処理するには以下のように指定します。
typerule: ^application/pdf${{!}}H@/usr/local/share/hyperestraier/filter/estfxpdftohtml
設定ファイルのdraftdir
やentitydir
という項目を指定した場合、クローラが取得した文書の文書ドラフトや実体データのファイルをそのディレクトリが保存されます。さらに、postproc
を指定すると、個々の文書を取得する度に、指定したコマンドが呼び出して後処理を行うことがれます。第1引数には保存した文書ドラフトのファイルのパスが、第2引数には保存した実体データのファイルのパスが渡されます。draftdir
やentitydir
を指定しないでpostproc
のみを指定した場合、テンポラリファイルが作成されてそのパスが引数として渡されます。
例えば、取得した文書をメールで送信するには、以下のようなシェルスクリプトを作って、そのコマンド名をpostproc
に指定します。
#! /bin/sh address="mikio@estraier.ad.jp" url=`sed -n -e '/^@uri/ s/^@uri=// p' "$1"` uuencode "$2" entity.dat | mail -s "[estwaver] $url" "$address"
適当な後処理のコマンドを用いれば、estwaver
をHyper Estraier以外の検索システムの収集エージェントとして用いることができます。文書管理システムのフロントエンドとして使ってもよいでしょう。後処理のみを行ってHyper Estraierのインデックスに文書を入れる必要がない場合は、設定ファイルのnoidx
の値を^http://
などとしてください。
Hyper Estraierのマニュアル群をここまで読み進めてくれたあなたは偉い! ついにWeb検索エンジンを構築する時が来ました。誰でも自分のWeb検索エンジンを持てるようにするという、Hyper Estraierの目標がここに結実します。ここではそのためのノウハウを説明します。
まずは、インデックスを管理するノードサーバを構築します。できるだけ大量の文書をできるだけ高速に検索するには、できるだけ多くのコンピュータで分散処理をさせた方が有利なのは言うまでもありませんが、とりあえずはPC1台でもWeb検索エンジンは実現できます。
PC1台で運用する場合にも、複数のノードサーバを用いた方がインデクシングの効率がよくなります。また、個々のノードサーバは別々のノードマスタ上で動かした方が効率がよくなります。その理由は、マルチプロセッサやマルチコアプロセッサの恩恵が受けやすくなることと、あるノードサーバがキャッシュをフラッシュしている間に別のノードサーバに登録先を割り振って処理速度の低下を抑止できることです。
ここでは、「ortho.estraier.ad.jp
」「para.estraier.ad.jp
」「meta.estraier.ad.jp
」という3台のPCを所有していることを想定します。それぞれ1GBの実メモリを搭載しているとします。それぞれに1つずつノードマスタとノードサーバを配置することにしましょう。以下に作業例を示しますが、ortho
、para
、meta
で同様の作業をしてください。
mkdir -p /home/mikio/var cd /home/mikio/var estmaster init master
適当なエディタで/home/mikio/var/master/_conf
を開いて、cachesize
の値を512にしてください。実メモリの搭載量が1GBならば、その半分くらいの容量のキャッシュを使うのが望ましいです。
ノードマスタをデーモンとして起動します。
estmaster start -bg master
ノードマスタのUI(Webブラウザでhttp://ortho.estraier.ad.jp:1978/master_ui
などに接続)を使って、管理者ユーザを設定します。ここではユーザ名が「mikio
」で、パスワードが「oikim
」ということにします。また、ノードサーバを作ります。ここでは名前を「child
」とし、ラベルはホスト名をつけることにします。
ortho
、para
、meta
の各ホストにノードサーバを構築したら、それらにメタ検索をするための親ノードを別に作ります。ここではortho
のノードマスタに作ることにして、名前は「parent
」でラベルは「estraier.ad.jp
」をつけることにします。
親ノードから各々の子ノードにリンクを張ります。この作業はどのホスト上で行っても構いません。
estcall setlink -auth mikio oikim http://ortho.estraier.ad.jp:1978/node/parent \ http://ortho.estraier.ad.jp:1978/node/child ortho 10000 estcall setlink -auth mikio oikim http://ortho.estraier.ad.jp:1978/node/parent \ http://para.estraier.ad.jp:1978/node/child para 10000 estcall setlink -auth mikio oikim http://ortho.estraier.ad.jp:1978/node/parent \ http://meta.estraier.ad.jp:1978/node/child meta 10000
うまく設置できているか確認するために、親ノードの検索用ユーザインターフェイス(http://ortho.estraier.ad.jp:1978/node/parent/master_ui
)に接続してください。そこで、「link#1: ortho
」「link#2: para
」「link#3: meta
」の3つのリンクが表示されているはずです。それぞれのリンクを選択してみて、それぞれのノードサーバのユーザインターフェイスに進めるかどうかも確認してください。なお、親ノードから間違ってリンクを張ってしまった場合は、10000の部分を-1に変えてestcall setlink
を実行してリンクを消してください。
クローラはmeta
で動かすことにします。クローラ用のディレクトリを設置します。
cd /home/mikio/var estwaver init waver
適当なエディタで/home/mikio/var/waver/_conf
を開いて、seed
に値に種文書の重み付けとURLを指定してください。プロクシを使う場合はproxyhost
やproxyport
も指定してください。また、日本語のサイトの文字コードの認識率を上げるために、language
も設定した方がいいでしょう。そして、取得した文書の登録先のノードも指定します。
seed: 1.5|http://fallabs.com/hyperestraier/ seed: 1.0|http://fallabs.com/estraier/ seed: 0.5|http://www.namazu.org/ ... proxyhost: proxy.estraier.ad.jp proxyport: 3128 ... language: 1 ... nodeserv: 1|http://ortho.estraier.ad.jp:1978/node/child nodeserv: 2|http://para.estraier.ad.jp:1978/node/child nodeserv: 3|http://meta.estraier.ad.jp:1978/node/child ...
nodeserv
でわざわざIDをつけているのは、ノードサーバのURLが変えられるようにするためです。estwaver
はどの文書をどのノードに登録したかをIDを使って記録して、文書が更新された時に古い情報を消します。したがって、IDさえ変えなければURLを変えても問題なく更新を行うことができるのです。
さて、いよいよクローラを実行します。-revcont
オプションは、既に取得した文書で再訪問周期になったもの(設定ファイルのrevisit
で指定)を巡回した上で新たな文書の巡回を継続する指定ですが、最初からつけていても問題はありません。
estwaver crawl -revcont waver
これで巡回された文書が続々と登録されていきます。親ノードの検索用ユーザインターフェイス(http://ortho.estraier.ad.jp:1978/node/parent/search_ui
)で確認してみてください。メタ検索を行うために、depth
の設定は1以上にしてください。
デフォルトの設定では10000件の文書を取得した時点でクローラは停止するようになっているので、もっとたくさん集めたい場合は設定ファイルのdocnum
の値を増やしてください。夜中などに定期的にクローラを走らせたい場合は、cron
などにestwaver
の起動スクリプトを登録しておくとよいでしょう。
設定が面倒で面目無いです。ほとんどの設定はノードAPIを使ったりREST風のリクエストを発行したりすれば自動化できるはずなんですが、その辺のインテグレーションは今後の課題ということで。なお、ノードAPIを使った検索アプリケーションを作ると、自前の検索エンジンを様々な用途に使えるようになると思います。ノードサーバのOpenSearch機能を利用して他の検索エンジンと連携させても面白いでしょう。
Web全体の検索エンジンはGoogleやYahooに任せておくとして、Hyper Estraierを使うと、Webの中でホットな部分に絞った検索システムを、インターネット上のユーザコミュニティが協調して構築できるようになります。estmaster
のP2P機構によってPC数台でも分散処理のインデクシングができるようにし、estwaver
の類似文書巡回機構によって興味のある文書を選択的に取得できるようにしているのはそのためなのです。インターネット上に設置されたノードサーバがどんどん増えて、それらが互いにリンクし合うようになれば、きっと面白い世界が見えて来るでしょう(いささか妄想気味)。