[[FrontPage]]
*Luceneとは? [#h0ca2407]
Jakarta Luceneは完全にJavaで書かれたハイパフォーマンスな全文検索エンジンのライブラリです。Luceneは全文検索が必要なアプリケーションに適しています。特にクロスプラットフォーム性を重視する場合は有用です。Javaの検索エンジンとしては、Namazu on Java2等もありますが、Namazu on Java2はライセンスがGPLで公開されており、(GPLが悪いという訳ではありませんが...)Namazu on Java2をアプリケーションに組み込むと開発したアプリケーションにもGPLが適用されます。LuceneはApache Software Licence 2.0で配布されており、アプリケーションに組み込んでもソースコードを公開する必要はありません(もちろん公開しても構いません)。LuceneはEclipseのヘルプの検索等、身近で利用されています。Luceneの優秀さは世界中の全文検索エンジンの研究者が認めるところであり、.NET、Ruby、Python、Perl、C++等の他の言語にもポーティングされています。
#br
Luceneの原作者であるDoug Cuttingさんは、以前はXeroxのPalo Alto 研究センター(PARC), Apple, Excite@Homeで検索エンジンを書いていました。そして、いくつかの情報検索システムに関する 論文や特許を書いています。ちなみに、Luceneは、ルシーン(Luceen)と発音します。

***参考文献 [#k42a86e5]
-The Lucene Search Engine
~http://www.javaranch.com/newsletter/200404/Lucene.html
-Query Parser Syntax
~http://jakarta.apache.org/lucene/docs/queryparsersyntax.html
-System Property
~http://jakarta.apache.org/lucene/docs/systemproperties.html
-File Format
~http://jakarta.apache.org/lucene/docs/fileformats.html
-IPADIC(形態素解析の辞書)マニュアル
~http://chasen.aist-nara.ac.jp/stable/doc/

*全文検索エンジンとは? [#c4e4fe62]
馬場 肇 さんの「日本語全文検索エンジンソフトウェアのリスト」を参照
#br
http://www.kusastro.kyoto-u.ac.jp/~baba/wais/other-system.html#fulltext_retrieval

*日本語環境について [#fa49eaf6]
残念ながら、Lucene自身は日本語を正しく扱うことはできません。一見正しく動いているように見えても、一部の文字がリジェクトされ正しくインデックスが作成されません。理由はアナライザというモジュールが正しく動作しないためです。アナライザは文書から単語を切り出すのですが、英語の場合単語が空白に区切られているんで、簡単に単語を抽出することができます。例えば、"I love Lucene"という文書があった場合、簡単に"I"、"love"、"Lucene"を切り出すことができます。しかし、日本語の場合は、"私はルシーンが好きです"となってしまい、単語の区切り目を検出することが困難です。
#br
Luceneは柔軟なプラグインアーキテクチャによって構成され、アナライザを自由にカスタマイズ可能となっています。日本語で利用できるアナライザを作成することにより、日本語で利用できるようになります。日本語で利用できるアナライザは現在の所、次の3つがあります。

***JapaneseAnalyzer [#c6011ec9]
日本語の分かち書きを行う手法の一つとして形態素解析があります。形態素解析は、例えば、
 Luceneは優秀な全文検索エンジンです。
という文書が合った場合、
 | Lucene | は | 優秀な | 全文検索 | エンジン | です |
と単語毎に区切ります。また、名詞、動詞等の品詞情報も同時に取得することができます。JapaneseAnalyzerでは、文書を単語に分割し、各単語の中で検索に重要でない単語を除いて登録します。例えば、助詞(は)や助動詞(です)等は上記の文書にとって重要でない単語なので省きます。残った単語をインデックスに登録します。

***CJKAnalyzer [#n689f173]
CJKAnalyzerは、中国語、日本語、韓国語に対応したアナライザです。CJKAnalyzerはbi-gramという手法を利用してCJKブロックの文書を単語に分割します。例えば、上記の例文は、
 | Lucene | は優 | 優秀 | 秀な | な全 ...
のように、日本語の部分が2文字づつずらした形で単語が切り出され登録されます。CJKAnalyzerは登録するインデックスの数が多くなるので、インデックスの辞書のサイズが多くなるのと、検索時にノイズが引っ掛かり易くなるという特徴があります。また、1文字の単語で検索したい場合、検索できないという問題もあります。しかしながら、これ一つで世界中の全ての言語をサポートできるのが大きな魅力です。

***NutchAnalyzer [#b3099cb4]
NutchAnalyzerはLuceneをベースとした全文検索エンジンNutchで利用されているアナライザでuni-gramという手法を利用したアナライザです。
 | Lucene | は | 優 | 秀 | な | 全 ...
と一文字づつ文字を切り出します。bi-gramと比べると一文字の単語が検索できないということはありませんが、検索結果にノイズが混じりやすくなり、インデックスのサイズも大きくなります。

*セットアップ [#x27b1f2b]
さて、ではLuceneを早速使ってみましょう。
ここでは、JapaneseAnalyzerを例にLuceneの利用方法を解説します。LuceneとJapaneseAnalyzerの利用には、次のソフトウェアが必要となります。
-Apache Ant
-Perl(Windowsの場合ActivePerl/Cygwinなど...)
-Sen
-Lucene-ja

まずは、各ソフトウェアをセットアップしていきましょう。既にご存知の方は適宜読み飛ばして下さい。

**Antのインストール [#k68b9ca3]
Apache Antのサイト
#br
http://ant.apache.org/bindownload.cgi
#br
からAntの最新版をダウンロードして適当なディレクトリに展開してインストールしてください。インストール後例えば、C:\ant-1.6.2にインストールした場合、環境変数のPATHにC:\ant-1.6.2\binを追加して下さい。

**Senのインストール [#ud2d4511]
Java.NETのSenのプロジェクト
#br
https://sen.dev.java.net/servlets/ProjectDocumentList?folderID=755&expandFolder=755&folderID=0
#br
からsenをダウンロード、適当なディレクトリで解凍(例えばc:\)し、dicディレクトリで次のようにして辞書を作成します。なお、辞書の作成にはperlが必要なので、Windows環境ではcygwinもしくはActivePerlをインストールしておいて下さい。

 c:\sen-1.0\dic> ant -Dperl.bin=c:/cygwin/bin/perl.exe 

辞書は、NAISTで配布しているIPADICを利用します。上記コマンドにより自動的にIPADICをダウンロードしSen用の辞書を作成します。

**Luceneのインストール [#o4ea7373]
上記のJava.NETのSenのプロジェクトからlucene-jaをダウンロードし、解凍します。lucene-javaには、Luceneが含まれているため、本家のLuceneをダウンロードする必要はありません。

*デモプログラムの実行 [#r5ecfee1]
LuceneにはファイルとHTMLからインデックスの生成と検索をデモプログラムが含まれています。ここでは、デモプログラムの利用方法を説明します。

**環境変数設定 [#p85feb73]
全てインストールが完了したら、環境変数の設定を行います。
+SEN_HOMEをsenをインストールしたディレクトリに設定
+LUCENE_HOMEをlucene-jaをインストールしたディレクトリに設定
+PATHに%LUCENE_HOME%\binを追加
例えば、次のようになります。
 C:\> SET SEN_HOME=C:\sen-1.0
 C:\> SET LUCENE_HOME=C:\lucene-ja-1.4
 C:\> SET PATH=%PATH%;%LUCENE_HOME%\bin

**インデックスの作成 [#f5fab829]
Luceneを使って検索するには、まずはインデックスに検索対象にしたいコンテンツを
登録します。インデックスの生成には、mktextndex.batもしくはmkhtmlindex.batを利用します。mktextindex.batはテキストファイルからインデックスを作成します。mkhtmlindexはご想像の通りHTMLファイルからインデックスを作成します。オプションは次の通りです([]内のオプションは省略可能)。

 mkhtmlindex.bat [-create] -index <インデックスのディレクトリ> <コンテンツのディレクトリ/ファイル>

インデックスのディレクトリにディレクトリもしくはファイルで指定したコンテンツ のインデックスが生成されます。-creataは新規にインデックスを作成するときだけ利用して下さい。一度作成したインデックスには、後からコンテンツを追加することができます。

**検索 [#y9d96452]
検索するには、search.batにインデックスのディレクトリを指定して実行します。
 search.bat <インデックスのディレクトリ>

*Webアプリケーションからの利用 [#rea06f62]

*Lucene API [#y16e09d4]
はっきりいって、付属のデモツールでできることは大したことはありません。Luceneの凄い所は、検索サービスを作成するために検索エンジンのプリミティブなAPIを提供しているところです。lucene-jaのorg.apache.lucene.demoパッケージにデモプログラムが入っていますので、そちらも参考にして下さい。

**インデックス作成 [#u82b1bfd]
インデックスを作成するには、下記の手順で行います。
+インデクサ(IndexWriterオブジェクト)の生成
+文書の登録
~下記の処理を各文書毎に繰り返す
++文書のフェッチ
++フィルタ処理
++ドキュメント(Documentオブジェクト)の登録
+インデクサのクローズ

さて、では実際にコードみながら、上記の処理をみていきましょう。

***1.インデクサの生成 [#i8e14824]
インデクサの作成は、IndexWriterインスタンスの作成によって行います。
 public IndexWriter IndexWriter(String index,Analyzer analyzer, boolean create)
-index: インデックスを作成するディレクトリ
-analyzer: アナライザ。日本語を利用する場合は、JapaneseAnalyzerを指定します。
-create: インデックスを新規に作成する場合はtrueを、既存のインデックスに文書を追加する場合はfalseを指定します。

例えば、
  System.property("sen.home", "C:/sen-1.0");
  IndexWriter writer = new IndexWriter("C:/home/okamoto/index", new JapaneseAnalyzer(), true);
のように指定すると、/home/okamoto/indexに新規にインデックスを作成します。なお、JapaneseAnalyzerを利用する場合は、システムプロパティのsen.homeにSenをインストールしたディレクトリを指定して下さい。

***2.文書の登録 [#vf67e3f8]

-フェッチ
文書のフェッチでは、登録対象のファイルを取得します。ここでは詳細は省略しますが、例えば下記のようにすると、あるディレクトリにあるファイルの一覧を取得できます。
   List list = ..
   String[] files = new File("c:\html").list();
   for (int i = 0; i < files.length; i++) {
     list.add(new File(files));
   }

-フィルタ
HTML文書やPDFの場合、そのままドキュメントをインデックスにすると、余分な文字(例えば、HTMLタグ)が混入したり、そもそも文書を抽出できなかったりします。そこで、フィルタ処理によって、インデックスに登録する文書を抽出します。ここでは詳細な処理は省略します。Lucene-ja付属のHTMLJDocuemnt等を参考にして下さい。

-ドキュメント登録
テキスト文書の登録を例に以下に示します。基本的には、Documentクラスのインスタンスに必要な情報を加えてIndexWriterで書き込みます。
    File f = new File("hoge.html");
    Reader reader = 
              new BufferedReader(
                     new InputStreamReader(
                        new FileInputStream(file),"Windows-31J));
 
    Document doc = new Document();
 
    // path属性にパス名を設定
    doc.add(Field.Text("path", f.getPath()));
 
    // modified属性にファイルの最新の更新時刻を設定
    doc.add(Field.Keyword("modified",
                          DateField.timeToString(f.lastModified())
                         )
            );
 
    // charset属性にキャラクタセットを設定
    doc.add(Field.Text("charset", charset));
 
    // contents属性にドキュメント本体のストリームを設定
    doc.add(Field.Text("contents", reader));
     
    // ドキュメントの書き込み
    writer.addDocument(doc);

ここでは、フィルタによって抽出したテキスト文書を検索エンジンのインデックスに登録します。

***3.インデクサのクローズ [#v461e374]
全てのドキュメントの登録が修了したらインデクサをクローズします。クローズするときは、インデクサの最適化を行ってからクローズします。
 writer.optimize();
 writer.close();
**検索 [#m0efa621]
インデックスを作成したら、次のようにして検索を実行します。
      //初期化処理
      System.setProperty("sen.home",...);
      Searcher searcher = new IndexSearcher("C:/home/okamoto/index");
      Analyzer analyzer = new JapaneseAnalyzer();
 
      String q = "検索キーワード";
 
      //クエリ生成
      Query query = QueryParser.parse(q, "contents", analyzer);
 
      // 検索実行&結果取得
      Hits hits = searcher.search(query);
  
      for (int i = 0; i < hits.length(); i++) {
             // i番目にヒットした文書を取得
	    Document doc = hits.doc(i);
             // 文書登録で設定した属性を取得
             String path = doc.get("path");
             String charset = doc.get("charset");
      }

*Nutchの利用 [#n6f81c96]
LuceneにPDF/Word/HTML用のフィルタとクローラを追加し、簡単に検索サービスを提供できるようにしたのがNutchです。Nutchは、Google等の大規模な検索エンジンと同様に分散アーキテクチャを採用しており、毎月1億ページ以上のページをインデックスに追加でき、1秒間に1000件以上の検索性能を得ることができると言われています。

*辞書のカスタマイズについて [#w66e52d2]
Senでは、奈良先端技術大学のIPADICを形態素解析用の辞書として利用しています。辞書をカスタマイズされたい方は、IPADICのマニュアル http://chasen.aist-nara.ac.jp/stable/doc/ をご覧ください。

*その他 [#r77362a9]
コメントなどありましたらお願いします。
-lucen + sen で検索ソフトをつくりましたが、辞書の性能が -- [[takoko]] &new{2004-08-28 (土) 01:35:09};
-すいません。上の続きです。当然ながら業務固有の名詞がうまく解析できなので、辞書に名詞などを追加登録したいのですが、どうやればよいのでしょうか?ご存知の方がいましたら、ご教受おねがいします。 -- [[takoko]] &new{2004-08-28 (土) 01:39:26};
-SenはIPADICを利用しています。IPADICのフォーマットについては奈良先端技術大学にあるIPADICのマニュアルをご覧下さい。 -- [[Oかもと]] &new{2004-09-02 (木) 01:18:47};
-luceneとsenを使って、検索ソフトを作ってみました。仕事場と家で2台のコンピュータがあるのですが、全く同じ環境(Windows2000)なのですが、何故か家のコンピュータでは次のようなエラーが出てしまいます。「Can't load a Japanese tokenizer」ソースを見ると、result = (TokenStream) Class.forName(tokenizer).getConstructor(types).newInstance(args);のところでキャッチされて、このメッセージを出しているようです。どなたか、原因がわかりませんか? -- [[chikkun]] &new{2004-10-27 (水) 21:44:55};
-Googleのような検索であれば、日本語のドキュメントでもLucenのみでできます。「日本語を正しく扱うことはできません」というのはどのような場合ですか? --  &new{2005-02-02 (水) 12:03:27};
-返答がなさそうなので追記。Lucenオリジナルのデモコードでは一部の文字(日本語を含む)をチェックしてはじいています。(理由はJavaCCに関係しています)このことでLucenのみでは日本語を扱えないと思っているようでしたら、それは勘違いです。日本語に対する効率的なインデックスが作成できないという意味であるのなら正しいかもしれませんが。つまり、ただ全文検索をするだけならSenは全く必要ありません。(少なくともvar1.4.3では確認しました) --  &new{2005-02-08 (火) 11:35:17};
-日本語と英語が混在しているドキュメントはどうしたものか。 例えばLuceneで検索すると、Luceneはこれをluceneにしてしまうのだが、インデックスに登録されているのはLucene。 これは自前でインデックス構築時にluceneにしちゃえばいいんですけどね(・ω・) 自前でなく、Luceneかsenの機能を使って実現する方法をご存知の方。 なにか初歩的な間違いの指摘などありましたら突っ込んでください。 -- [[サン]] &new{2005-02-17 (木) 03:33:34};
-14 February 2005 - Lucene moves to Apache top-level  おめでとう! -- [[anyontv]] &new{2005-03-11 (金) 10:28:03};
-最近、プロジェクト推進のため、MSDNような検索サイトをつくりたいです。LunceneとSenを利用して、できるかなとやってみます。 -- [[胡 春強]] &new{2005-04-02 (土) 07:12:18};
->>3つ上 お使いのAnalyzerが使用しているLowerCaseFilter(org.apache.lucene.analysis.LowerCaseFilter)をはずせばいいのでは?詳しくはjavadoc(http://lucene.apache.org/java/docs/api/index.html)を参照のこと。  >>4つ上 StandardAnalyzerでは一部の特殊フォント(JIS X 0208 規格外文字)が存在する場合などで結果がうまくでないことが多い(そこそこはでるんだけどね・・・)。ただ、このサイトで紹介されているlucene-jaって本家とは何の関わりもないんだよね。"Sen for Lucene --  &new{2005-04-06 (水) 22:34:03};
-LuceneでWORD、POWERPOINTといったドキュメントの検索は可能でしょうか? -- [[SAKURA]] &new{2005-08-09 (火) 17:39:43};
-http://wiki.apache.org/jakarta-lucene/LuceneFAQ に書いてありますが、wordなどのドキュメントは一度不要な情報を省いてテキスト状態にしてからindexします。なので、必要事項をファイルから抽出するapiが提供されてるならどんなファイルも検索対象になります。 -- [[汰銀具]] &new{2005-08-22 (月) 08:17:19};
-Luceneを使って、Senをいらなくても、簡単に検索機能はできますが、URLに漢字があればそのページがアクセスできません。Namazuもこの問題があります。最後はMsのIndexServiceで解決できました。 -- [[胡 春強]] &new{2005-10-15 (土) 03:38:30};
- KvwYBhfs -- [[tidus.ultimania.org]] &new{2011-06-02 (木) 06:09:11};

#comment

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS