はじめに
本連載では、PHP上で動作するアプリケーションフレームワークであるZend Frameworkについて紹介していきます。今回はZend_Search_Luceneモジュールの紹介の2回目で、Zend_Search_Luceneの詳細について説明します。
前回の記事ではZend_Search_Luceneを使った索引の作成方法と検索の方法について基本的なところを一通り見てみました。今回はZend_Search_Luceneの動作の仕組みも見ていきながら、もう少し詳細な検索の方法や索引の作成について説明していきたいと思います。
対象読者
PHPの基本構文は一通り理解しているが、フレームワークを利用したことはないという方を対象としています。
必要な環境
Zend FrameworkはPHP 5.1.4以降とWebサーバがインストールされている環境で利用可能です。本稿ではWebサーバとしてApache 2.2を、OSにWindows XPを採用し、アプリケーションを作成していきます。
以下に、今回アプリケーション作成/動作確認に用いた環境を示します(インストールにあたっては最新安定版の使用を推奨します)。各項目の詳細なインストール手順は、「サーバサイド技術の学び舎 - WINGS」より「サーバサイド環境構築設定手順」を参照ください。
- Windows XP SP2
- PHP 5.2.9-2
- Apache 2.2.11
LinuxやFreeBSDなどUNIX系OSをお使いの方もコマンドはほぼ一緒ですので、パスなどは適宜読み替えてください。
また、今回の後半で紹介するApache Luceneを利用した索引の作成はJava環境を必要とします。こちらについての動作確認は次の環境で行いました。
- SUN Java SE Development Kit (JDK) 6
- Apache Lucene 2.0.0
- Lucene-ja 2.0test2
JDK6は、「Java SE ダウンロード」のページからダウンロードできます。ここにある「Java SE Development Kit (JDK) 6 Update XX」の右の[ダウンロード]のボタンをクリックすると、JDK6を利用する環境を入力する画面が表示されます。ここでOSと言語(「Windows」と「Multi-language」)を選択し、ライセンスに同意する旨をチェックして「Continue」をクリックするとダウンロードするファイルを選択する画面が表示されます。ここで「jdk-6uXX-windows-i586-p.exe」と書かれたリンクをクリックし、ダウンロードされたファイルを実行すればJDKのインストールが開始されます。
また、Lucene-jaはプロジェクトのサイトから「lucene-ja-2.0test2.zip」をダウンロードします:
Apache LuceneはこのLucene-jaに含まれているものを利用するので、別途準備する必要はありません。
文字列の扱い
まず最初に、Zend_Search_Luceneでの文字列の扱いについて詳しく見てみます。Zend_Search_Luceneでは索引を作成する時もクエリを作成するときも、文字列の解析を行っています。これには、与えられたファイルに含まれる文字列を単語(正確にはトークン)に区切ったり、大文字を小文字に正規化したりする処理などが考えられます。
この文字列の処理は、Zend_Search_Lucene_Analysis_Analyzer
クラスのオブジェクトが担当します。利用する文字列解析オブジェクトによって、実際にどのように扱われるかが決まります。標準では、ASCII文字列を前提とし、アルファベットの大文字と小文字を区別しないように設定されています。
文字列解析オブジェクトの設定
テキスト解析を行うオブジェクトは、Zend_Search_Lucene_Analysis_Analyzer
のsetDefault静的メソッドで設定することができます。また、getDefault静的メソッドを利用すれば、同じく現在利用されているテキスト解析のオブジェクトを取得することができます。
標準で準備されてるテキスト解析クラスは、おおまかに 2系統(ASCII文字列を扱う「Text」とUTF-8を扱う「UTF8」)があります。それにさらに、クラス名に「Num」がついたものは文字と数字を同等に扱い、「_CaseInsensitive」は大文字と小文字を区別しない(内部ではすべて小文字に変換して処理しています)というバリエーションがあります。例えばZend_Search_Lucene_Analysis_Analyzer_Common_TextNum_CaseInsensitive
は単語としてアルファベットと数字の交じったものを受け付け、大文字と小文字を区別しない文字列解析オブジェクトとなります。また、標準ではZend_Search_Lucene_Analysis_Analyzer_Common_Text_CaseInsensitive
クラスのオブジェクトが利用されるように設定されています。
クラス名 | 説明 |
Text | テキストをASCII文字列として扱い、単語はアルファベットから構成されるとする |
Text_CaseInsensitive | テキストをASCII文字列として扱うが、大文字と小文字は区別しない |
TextNum | テキストをASCII文字列として扱い、単語はアルファベットと数字から構成されるとする |
TextNum_CaseInsensitive | テキストをASCII文字列として扱い、大文字と小文字は区別しない。また、単語はアルファベットと数字から構成されると扱う |
Utf8 | テキストをUTF-8の文字列として扱う |
Utf8_CaseInsensitive | テキストをUTF-8の文字列として扱うが、大文字と小文字は区別しない |
Utf8Num | テキストをUTF-8の文字列として扱い、単語はUTF-8の文字と数字から構成されるとする |
Utf8Num_CaseInsensitive | テキストをUTF-8の文字列として扱い、大文字と小文字を区別しない。また、単語はUTF-8の文字と数字から構成されるとする |
//文字列解析オブジェクトをUTF8を受け付けるものに設定 Zend_Search_Lucene_Analysis_Analyzer::setDefault( new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8());
リスト1では文字列解析を行うオブジェクトに、内部でUFT8を利用しているものを設定しています。日本語などの、アルファベット以外の文字を利用している場合には最低限この設定を行う必要があります。
なお、日本語を扱う際にはこれだけでは単語に分解してくれないため、ほとんどの場合では処理としては不十分です。ここの処理については後で紹介するApache Luceneとの連携で、もう少し説明します。
文字列の加工
テキスト解析オブジェクトには文字列を解析する際に対象とした文字列を加工するフィルタを設定することができます。例えば、大文字と小文字を区別しない機能は、入力文字列を小文字に変換するフィルタで実現されています。
標準では次の 4つのフィルタが準備されています:
クラス名 | 説明 |
StopWords | 除去する単語の設定 |
LowerCase | 文字列を小文字にする |
LowerCaseUtf8 | UTF8に対応したLowerCaseフィルタ |
ShortWords | 長さの短い単語を除去。コンストラクタで長さを設定する(標準では2) |
例えば「these, they, those, that」と、3文字以下の長さの単語を除去するフィルタを利用してテキストを解析するにはリスト2のように記述します。
//文字列解析オブジェクトをUTF8を受け付けるものに設定 $analyzer = new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8(); //次の単語は無視 $stopWords = array('these', 'they', 'those', 'that'); $stopWordsFilter = new Zend_Search_Lucene_Analysis_TokenFilter_StopWords($stopWords); $analyzer->addFilter($stopWordsFilter); //長さの短かい単語は無視 $shortWordsFilter = new Zend_Search_Lucene_Analysis_TokenFilter_ShortWords(3); $analyzer->addFilter($shortWordsFilter); //この文字列解析オブジェクトを利用するように設定 Zend_Search_Lucene_Analysis_Analyzer::setDefault($analyzer);