目次
Zend_Search_Lucene は、完全に PHP 5 で書かれている汎用的なテキスト検索エンジンです。 インデックスをファイルシステム上に保存するためデータベースサーバを必要とせず、 たいていの PHP ウェブサイト上で動作させることができます。 Zend_Search_Lucene は、以下の機能をサポートしています。
重要度による検索 - 最もマッチした結果が最初に返されます
さまざまな強力な検索方式: フレーズ検索、ワイルドカード検索、 あいまい検索、範囲指定検索などなど [7]
指定したフィールド (例: タイトル、作者、内容) による検索
Zend_Search_Lucene は Apache Lucene プロジェクトから派生したものです。 Lucene についての詳細は http://lucene.apache.org/java/docs/ を参照ください。
Zend_Search_Lucene は、ドキュメント単位でインデックスを作成します。 ドキュメントは名前つきのフィールドから構成され、 検索対象のコンテンツがフィールドの中に含まれます。
ドキュメントを表すのが Zend_Search_Lucene_Document オブジェクトです。このオブジェクトの中には、フィールドを表す Zend_Search_Lucene_Field オブジェクトが含まれます。
あらゆる種類の情報がインデックス化される可能性があることに注意しましょう。 アプリケーション固有の情報やメタデータをドキュメントのフィールドに格納し、 検索結果のドキュメントとして後で取得することができます。
インデクサを制御するのは、あなたが作成するアプリケーションの役割です。 ということは、あなたのアプリケーションからアクセス可能な、 あらゆる内容のデータがインデックス化される可能性があるということです。 例えばファイルシステム、データベース、HTML フォームなどが考えられます。
Zend_Search_Lucene_Field クラスには、
さまざまな性質のフィールドを作成するための静的メソッドが定義されています。
<?php
$doc = new Zend_Search_Lucene_Document();
// フィールドはトークン化されませんが、インデックス化されて保存されます。
// 保存されたフィールドは、インデックスから取得することができます。
$doc->addField(Zend_Search_Lucene_Field::Keyword('doctype',
'autogenerated'));
// フィールドはトークン化もインデックス化も行われませんが、インデックスに保存されます。
$doc->addField(Zend_Search_Lucene_Field::UnIndexed('created',
time()));
// バイナリ文字列フィールドはトークン化もインデックス化も行われません。
// しかしインデックスには保存されます。
$doc->addField(Zend_Search_Lucene_Field::Binary('icon',
$iconData));
// フィールドがトークン化・インデックス化されてインデックスに保存されます。
$doc->addField(Zend_Search_Lucene_Field::Text('annotation',
'Document annotation text'));
// フィールドはトークン化されてインデックス化されますが、インデックスには保存されません。
$doc->addField(Zend_Search_Lucene_Field::UnStored('contents',
'My document content'));
?>
これらの各メソッド (Zend_Search_Lucene_Field::Binary()
メソッドを除く) は、オプションのパラメータ
$encoding を持っています。これで入力データのエンコーディングを指定します。
エンコーディングはドキュメントによって異なるでしょうし、 同一ドキュメント内でもフィールドによって異なることもあるでしょう。
<?php
$doc = new Zend_Search_Lucene_Document();
$doc->addField(Zend_Search_Lucene_Field::Text('title', $title, 'iso-8859-1'));
$doc->addField(Zend_Search_Lucene_Field::UnStored('contents', $contents, 'utf-8'));
?>
エンコーディングパラメータを省略した場合は、 現在のロケールが処理時に使用されます。たとえば次のようになります。
<?php
setlocale(LC_ALL, 'de_DE.iso-8859-1');
...
$doc->addField(Zend_Search_Lucene_Field::UnStored('contents', $contents));
?>
フィールドをインデックス化したり返したりする際には、 常に UTF-8 エンコーディングとなります。UTF-8 への変換は自動的に行われます。
テキスト解析器 (以下を参照ください) は、テキストをその他のエンコーディングに変換したりもします。 実際、デフォルトの解析器はテキストを 'ASCII//TRANSLIT' エンコーディングに変換します。 ここで注意が必要なのは、このような変換は現在のロケールに依存して行われるということです。
フィールドの名前は自由につけることができます。
Java Lucene は、検索の際にデフォルトで使用されるフィールド名として "contents" を使用します。 Zend_Search_Lucene は、デフォルトではすべてのフィールドを検索します。 しかし、この挙動を変更することもできます。詳細は "デフォルトの検索フィールド" の章を参照ください。
Keyword フィールドは、保存されインデックス化されます。
つまり、検索した際に元の内容がそのまま返されるということです。
トークン化は行われません (いくつかの単語に分割されることはありません)。
列挙方のデータベースフィールドは、通常は Zend_Search_Lucene の
Keyword フィールドにうまく収まることでしょう。
UnIndexed フィールドは検索対象になりませんが、
検索結果としては返されます。このフィールドに設定する値としては、
データベースのタイムスタンプ、主キー、ファイルシステムのパス
およびその他の外部識別子などがあります。
Binary フィールドは、トークン化もインデックス化も行われません。
しかし、検索結果として取得できるように保存されます。
画像アイコンのようなバイナリデータをバイナリ文字列として
エンコードしたものなどに対して使用します。
Text フィールドは、保存されインデックス化され、
そしてトークン化されます。検索項目として使用し、
かつ検索結果としても取得したいような項目、
例えばタイトルなどを保存するのに適しています。
UnStored フィールドはトークン化されインデックス化されます。
しかしインデックスには保存されません。大量のテキストなどに適しています。
データを保存してしまうとディスク上のインデックスのサイズが大きくなってしまうので、
検索はしたいが結果としてそれを表示する必要がない場合などは、
このフィールドを使用しましょう。Zend_Search_Lucene インデックスを
リレーショナルデータベースと組み合わせて使用する場合などには
UnStored フィールドが実用的に使用できるでしょう。
大きなデータフィールドの内容の検索用に UnStored フィールドに保存し、
結果をデータベースから取得するために、もうひとつ別の ID フィールドを使用します。
Zend_Search_Lucene には HTML をパースする機能もあります。 次のようにして、HTML ファイルや文字列からドキュメントを直接作成することができます。
<?php $doc = Zend_Search_Lucene_Document_Html::loadHTMLFile($filename); $index->addDocument($doc); ... $doc = Zend_Search_Lucene_Document_Html::loadHTML($htmlString); $index->addDocument($doc); ?>
Zend_Search_Lucene_Document_Html クラスは、
DOMDocument::loadHTML() および
DOMDocument::loadHTMLFile() メソッドを用いてソース HTML
をパースしています。つまり、対象となる HTML は整形式である必要はなく、
また XHTML である必要もありません。一方、ヘッダの "meta http-equiv"
タグで、エンコーディングをきちんと設定しておく必要があります。
Zend_Search_Lucene_Document_Html クラスは、
ドキュメントのタイトル、本文そしてヘッダの meta タグの内容を認識します。
'title' フィールドには /html/head/title の値が入ります。 これはインデックスないにトークン化して保存され、検索の対象となります。
'body' フィールドには body の中身が入ります。 スクリプトやコメント、そしてタグの属性は含まれません。
Zend_Search_Lucene_Document_Html クラスの
loadHTML() および loadHTMLFile() メソッドには、
オプションの二番目の引数もあります。これを true に設定すると、
body の中身もインデックスに格納され、インデックスから取得できるようになります。
body はトークン化とインデックス化だけが行われ、デフォルトでは保存されません。
ドキュメントヘッダの meta タグの内容をもとに、追加のフィールドを作成します。 フィールドの名前は 'name' 属性から取得します。そして 'content' 属性の内容がその値となります。これはトークン化、インデックス化した上で 保存されます。つまり、ドキュメントは meta タグの内容をもとにして (たとえばキーワードによって) 検索できるようになるわけです。
パースされたドキュメントに、ユーザが別のフィールドを拡張することができます。
<?php
$doc = Zend_Search_Lucene_Document_Html::loadHTML($htmlString);
$doc->addField(Zend_Search_Lucene_Field::UnIndexed('created',
time()));
$doc->addField(Zend_Search_Lucene_Field::UnIndexed('created',
time()));
$doc->addField(Zend_Search_Lucene_Field::Text('annotation',
'Document annotation text'));
$index->addDocument($doc);
?>
作成されたドキュメントにはリンクは含まれません。しかし、
Zend_Search_Lucene_Document_Html::getLinks() および
Zend_Search_Lucene_Document_Html::getHeaderLinks()
メソッドでリンクを取得することもできます。
<?php $doc = Zend_Search_Lucene_Document_Html::loadHTML($htmlString); $linksArray = $doc->getLinks(); $headerLinksArray = $doc->getHeaderLinks(); ?>