Lucene-ja

 

早稲田大学 人間科学部 菊池英明
 

(2008/06/28) 公開

 

本文書の目的

ウェブ検索エンジンのフリーソフトLuceneをベースとして日本語解析機能が加えられたLucene-jaを用いて、ウェブ検索エンジンを構築する方法を解説する。

参考

Lucene-ja

Luceneのクラスについてのリファレンス

 

0. Lucene-jaのインストール

 

こちらのセットアップを参考にしてインストールすればよい。一部、Windowsに応じた記述になっているので、Unix用に以下に解説する。

0.1 Antのインストール

0.2 Senのインストール

こちらも参照されたい。

簡単に書けば、ここからsen-1.2.2.1.zipをダウンロードして解凍する。

% unzip sen-1.2.2.1.zip

これでsen-1.2.2.1ディレクトリができる。

その後、辞書を作成する。

% cd sen-1.2.2.1
% cd dic
% ant
BUILD SUCCESSFUL

0.3 Lucene-ja+Senのインストール

ここ から lucene-ja-1.4.3sen1.2-2.zipをダウンロードして解凍する。

% unzip lucene-ja-1.4.3sen1.2-2.zip

これでlucene-jaディレクトリができる。

0.4 クラスパスの設定

Senおよびlucene-jaのjarファイルにCLASSPATHを通す。
sen: sen-1.2.2.1/lib/sen.jar
lucene-ja: lucene-ja/lib/lucene-ja.jar, その他libディレクトリ下にある全てのjarファイル(sen.jarは上と重複するのでどちらかにする)

0.5 動作確認

% cd lucene-ja

% java org.apache.lucene.demo.IndexFiles docs-ja

adding docs-ja/demo.html
adding docs-ja/demo2.html
adding docs-ja/demo3.html
adding docs-ja/gettingstarted.html
adding docs-ja/index.html
adding docs-ja/powered.html
adding docs-ja/resources.html
adding docs-ja/whoweare.html
780 total milliseconds

% java org.apache.lucene.demo.SearchFiles

Query: Lucene

Searching for: lucene
8 total matching documents
0. docs-ja/index.html
1. docs-ja/resources.html
2. docs-ja/demo.html
3. docs-ja/gettingstarted.html
4. docs-ja/powered.html
5. docs-ja/whoweare.html
6. docs-ja/demo2.html
7. docs-ja/demo3.html

こんな感じで動けばOK。

1. Lucene-jaの構成

参考:lucene-ja/docs-ja/gettingstarted.html

赤字が自身で開発する際のポイント。

なお、開発手順については要点を整理して2に示す。

1.1 Lucene-jaのソースコードを展開

lucene-jaディレクトリにあるlucene-ja-src.jarを展開する。

% cd lucene-ja

% jar xvf  lucene-ja-src.jar

これで orgディレクトリができる。

orgディレクトリの中身

 org-apache-lucene-analysis-{cjk,ja}

 org-apache-lucene-demo

ここに以下のJavaプログラムのソースコードがある。

CharsetDetector.java //文字コード判別

FileJDocument.java //HTML以外のインデクサー(1ファイル)

HTMLJDocument.java //HTML文書のインデクサー (1ファイル)

IndexJFiles.java //HTML以外のインデクサー(ディレクトリ)

IndexJHTML.java//HTML文書のインデクサー (ディレクトリ)

SearchJFiles.java //サーチャー

※これらを用いてor見本にして自分のインデクサープログラムを書けばよい。

1.2 Webアプリを動かす

まずTomcatが必要。 (参考)

lucene-jaディレクトリにあるwebappディレクトリをtomcatのwebappsディレクトリにコピーする。

% cd lucene-ja

% cp -rf webapp tomcatのディレクトリ/webapps/lucene-ja

これでtomcatを再起動して、http://サーバ名:8080/lucene-ja/にアクセスすれば以下のようなページが開くはず。

このページに書かれている指示にしたがってtomcat上でlucene-jaのウェブアプリを動かすための設定を行う。

0. CATALINA_HOMEの設定

上のページに書かれていないが、tomcatの設定の際に、あらかじめ設定ファイル(たとえば/root/.bashrc)に環境変数CATALINA_HOMEを正しく設定しておくこと。

export CATALINA_HOME=/usr/local/apache-tomcat-5.5.25-src/build/build/

1. catalina.(bat|sh)にsen.homeの設定を記述

JAVA_OPTS="$JAVA_OPTS "-Dsen.home=sen-1.2.2.1のディレクトリ" "-D
java.util.logging.manager=org.apache.juli.ClassLoaderLogManager" "-Djava.util.lo
gging.config.file="$CATALINA_BASE/conf/logging.properties"

2. 検索したいコンテンツ(ディレクトリYYYに含まれる)をこのディレクトリ(%CATALINA_HOME%\webapps\XXX)にコピー。XXXはこのWebアプリケーションをコピーしたディレクトリ名(ここではlucene-jaという名前で説明する)

root% cd tomcatのディレクトリ/webapps/lucene-ja

root% cp -rf lucene-jaディレクトリ/docs-ja .

3. lucene-jaに含まれるmkhtmlindex.(bat|sh)でインデックスを作成

% cd lucene-ja

% chmod +x bin/*.sh

% bin/mkhtmlindex.sh -create -index index/ docs-ja/

これでlucene-jaディレクトリの下のindexディレクトリにdocs-jaディレクトリ内のHTML文書に対するインデックスが作成される。

"docs-ja"としたところに適当なディレクトリを指定すれば、そこにある文書についてのインデックスが作成されることになる。

4. configuration.jspをmkhtmlindex.shで指定したindexディレクトリに合わせて修正

String indexLocation = "lucene-jaのディレクトリ/index ";

5. tomcatを再起動して、http://サーバ名:8080/lucene-ja/にあらためてアクセス

これで 検索窓に"Lucene"などと入力して検索すれば、該当する文書がヒットする。

※これらを用いてor見本にして自分のサーチャープログラムを書けばよい。

2. Lucene-jaを用いた検索エンジンの開発手順

サーバ上でlucene-jaとtomcatのインストールを行い、設定が完了していれば、以下のような手順で検索エンジンを稼動できる。

なお、tomcat関係の管理はroot権限が望ましい。
また、lucene関係にclasspathを通しておく。

1) インデックスファイルを作る

a) 対象がHTMLである場合
% java org.apache.lucene.demo.IndexHTML -create -index インデックスファイルを置く場所 インデックスを作成したい対象

 
※インデックスファイルを置く場所については、tomcatがいじれるように読み書きのパーミッションをあけておく必要がある。


b) 対象がテキストファイルである場合
% cd インデックスを作りたい場所
% java org.apache.lucene.demo.IndexJFiles インデックスを作りたい対象のディレクトリ
※実際にはテキストファイルが対象だと、検索結果に表示する情報をインデクサーが準備しなければならず(例えば講義テキストならば講義タイトル、話者名など)、インデクサーは自前で作る必要がある。


2) tomcat内に検索アプリ用のディレクトリを作る(lucene-jaのwebappをコピーすると良い)

root% cd tomcatのディレクトリ/webapps
root% cp -rf lucene-jaのディレクトリ/webapp 検索アプリ名

3) 検索アプリのディレクトリ内のconfiguration.jsp内でインデックスの場所を設定

"indexLocation"の値を修正する。

これでtomcatを再起動して、ブラウザ上でhttp://サーバ名:8080/検索アプリ名/にアクセスすれば、検索窓が開き、検索ができる。

(ただし検索結果中の日本語(2バイト文字)は文字化けするし、日本語の検索もヒットしない)

3. 日本語文書の扱い

lucene-jaのサンプルサーブレットresults.jspはShift-JISでエンコードされていた。

lucene-jaディレクトリ内のdocs-jaディレクトリにあるHTML文書はShift-JISでエンコードされている。これを対象にインデックスを作って検索すると、検索結果中の日本語(2バイト文字)は文字化けするし、日本語の検索もヒットしない。

詳細にみてみた。

index.jsp

ヘッダに

 page pageEncoding="Windows-31J"

 charset=Windows-31J

とある。

results.jsp

ヘッダに

 page pageEncoding="Windows-31J"

 charset=Windows-31J

とある。

 

ソースコード中:

 request.setCharacterEncoding("Windows-31J");

通信用語の基礎知識によれば、"Windows-31J"とはShift-JISの拡張らしい。

このあと、

 queryString = request.getParameter("query");

とやっているのだから、取得したクエリ文字列はこの時点でWindows-31Jで円コーディングしているのだろう。

queryStringは、

 query = QueryParser.parse(queryString, "contents", analyzer);

 (中略)

 hits = searcher.search(query);

と検索に使われる。

(searcherはIndexSearcherクラスのインスタンス)

IndexSearcher.search(Query query)

特に文字列エンコーディングについての扱いは触れられていない。

IndexJHTML

インデクシングに用いたこのプログラムの中で、インデクシング対象の文書の文字コードの扱いは以下のようになされる。

 

String charset = System.getProperty("file.encoding");

// システムのデフォルトのファイルエンコーディングを得る。

if (argv[i].equals("-index")) { // parse -index option
  index = argv[++i];
} else if (argv[i].equals("-charset")) { // parse -charset option
  charset = argv[++i];
}

// 起動時のcharsetオプションでファイルエンコーディングを得る。

// なお、このIndexJHTMLクラスを起動するスクリプトmkhtmlindex.shには特にcharsetオプションを指定していない。

したがって、charsetにはシステムのデフォルトのファイルエンコーディング(debianの場合はUTF-8?)が指定される。

この後、指定されたcharsetに基づいてインデクシングを行う。

indexDocs(root, index, create, charset);

(中略)

Document doc = HTMLJDocument.Document(file, charset);

HTMLJDocument

IndexJHTMLから呼び出される、1ファイルずつのインデクシング処理部であるこのクラスでは、charsetに対して以下のようにふるまう。

if (charset == null) {
 try {
  CharsetDetector cd = new CharsetDetector(f);
  charset = cd.detect();
 } catch (Exception e) {
  e.printStackTrace();
  charset = "ISO-8859-1";
 }
}

つまり、呼び出されるときにcharsetが指定されていなかったら自動判別を行い、判別に失敗したら"ISO-8859-1"が設定されるということ。

なお"ISO-8859-1"とはWesternのコード名である。

 

FileJDocument

インデクシングに用いたこのプログラムの中で、インデクシング対象の文書の文字コードの扱いは以下のようになされる。

 CharsetDetector cd = new CharsetDetector(f);
 charset = cd.detect();
 reader = new BufferedReader (new InputStreamReader(is, charset));
} catch (Exception e){
 e.printStackTrace();
}
doc.add(Field.Text("charset", charset));
doc.add(Field.Text("contents", reader));

つまり、文書の文字コードをここで自動判別して、その結果に応じた文字コードで文書を読み込み、そのまま"contents"フィールドに文書内容を格納する。

一方、判別した文字コードは"charset"フィールドに格納される。

以上のことから、おそらく、Lucene-jaのデモでインデクシング・検索をする場合には、インデクシング対象の文書がShift-JISになっている必要があるということだろう。

IndexJHTMLの方はどうもcharsetの自動設定がうまくいっていない様子。

IndexJFile(FileJDocument)の方はうまくいっていそうなので、ためしに上のmkhtmlindex.shをやめてmktextindex.shでインデックスを作成し、results.jspをこれにあわせて修正する(urlフィールドやtitleフィールドはないので他の何かで代用する) と、日本語の検索はうまくいくようになった。

参考:文字コードcharset


 

Copyright ©2008 KIKUCHI Hideaki All rights reserved.