はじめに
本連載では、PHP上で動作するアプリケーションフレームワークであるZend Frameworkについて紹介していきます。今回はテキスト検索エンジンのZend_Search_Luceneコンポーネントの紹介を行います。
Zend_Search_Luceneは完全にPHPで書かれたテキスト検索エンジンで、ローカルのファイルに索引を持つため、他のプログラム等に依存せずに利用することができます。HTMLファイルやOffice 2007のファイル(Word 2007、PowerPoint 2007、Excel 2007のファイル)から索引を作る機能を持っているため、 手軽に手元にあるファイルの索引を作成して管理することができます。また、名前の通り索引の形式がApache Luceneと互換性があるため、Apache Luceneで作成した索引をZend_Search_Luceneで利用することも可能です。
今回はZend_Search_Luceneの索引の作成から検索までの基本的な使い方を、単体アプリのサンプルを見ながら紹介していきたいと思います。
なお、Zend_Search_LuceneはUTF-8で処理を行うことができるため、日本語を含むテキストを扱うこと自体は可能ですが、日本語の分かち書きに対応していないため、標準では日本語の単語をキーワードにした索引の作成はできません。日本語の扱いについては、次回扱う予定です。
対象読者
PHPの基本構文は一通り理解しているが、フレームワークを利用したことはないという方を対象としています。
必要な環境
Zend FrameworkはPHP 5.1.4以降とWebサーバがインストールされている環境で利用可能です。本稿ではWebサーバとしてApache 2.2を、OSにWindows XPを採用し、アプリケーションを作成していきます。
以下に、今回アプリケーション作成/動作確認に用いた環境を示します(インストールにあたっては最新安定版の使用を推奨します)。各項目の詳細なインストール手順は、「サーバサイド技術の学び舎 - WINGS」より「サーバサイド環境構築設定手順」を参照ください。
- Windows XP SP2
- PHP 5.2.9-1
- Apache 2.2.11
LinuxやFreeBSDなどUNIX系OSをお使いの方もコマンドはほぼ一緒ですので、パスなどは適宜読み替えてください。
Zend_Search_Luceneについて
Zend_Search_Luceneはテキスト検索エンジン、すなわちあらかじめ登録されているテキスト文書から与えられた条件に合致する文書を探し出すシステムです。上でも紹介したとおり、Zend_Search_Luceneは完全にPHPで書かれており索引もローカルファイルに保存するため、他のライブラリやシステムに依存せず利用することができます。
Zend_Search_Luceneは、基本的に
- 検索対象の文書の登録(索引の作成)
- 条件を応じた文書を検索
という2段階で利用します。
ここで、簡単なサンプルを見てみましょう。このサンプルでは、まず「codezine-index」という索引を作成し、「test.html」というファイルの中身を登録しています。次に作成した索引に対して「Test」という文字列で検索をかけて、その結果を表示しています。
<?php require_once 'Zend/Search/Lucene.php'; //文字コードに関するおまじない(次回説明) Zend_Search_Lucene_Analysis_Analyzer::setDefault( new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8()); // (1) - 索引の作成 $index = Zend_Search_Lucene::create('codezine-index'); // (2) - 文書の作成とHTMLの解析 $doc = Zend_Search_Lucene_Document_Html::loadHTMLFile('test.html'); // (3) - 索引へ文書の登録 $index->addDocument($doc); // (4) - 検索と実行 $hits = $index->find('Test'); // (5) - 検索結果の表示 foreach ($hits as $hit) {//合致した各文書について echo "score ".$hit->score."\n"; $doc = $hit->getDocument(); foreach ($doc->getFieldNames() as $field_name) {//文書の内容を見る echo $field_name.":".$doc->getFieldValue($field_name)."\n"; } }
リスト1の例では(1)~(3)で索引の作成を、(4)と(5)で検索の実行と結果の表示を行っています。(1)では「codezine-index」という名前の索引を作成し、(2)で「test.html」を解析し、登録の準備をしています。(3)では(2)で準備した情報を索引に登録しています。
(4)では「Test」という文字列を含む文書を検索するクエリを作成し、そのクエリで検索を実行しています。その検索結果は変数$hitsに格納されています。
最後に$hitsの内容を表示しているのが(5)です。$hitsの内容は配列になっており、各要素の中には条件に合致した文書が格納されています。(5)の外側のforeach文で、合致した各文書を見ており、内側のforeachではその文書の内容を表示しています。
リスト1を実行した結果をリスト2に示します。
C:\codezine>php test.php score 0.28478324365611 title:Test generator:Hand Generated
今回は1つしか文書を登録しておらず、その文書が検索の条件に合致するので、1つの結果が表示されています。
このうち、「score 0.28478324365611」がリスト1の「echo "score ".$hit->score."\n";」に対応しており、この文書が検索の条件にどれだけ合致していたかを示しています。その次の2行がリスト1の「文書の内容を見る」部分の出力になっています。
索引の実体はどのようになっているのでしょう? 上のサンプルを実行した後のファイル構成を見てみると「codezine-index」というディレクトリができているのが分かると思います。索引に関するファイル一式が作成され、このディレクトリの中に置かれています。
それでは、まず索引を生成する方法について見ていきます。