関口宏司のLuceneブログ

OSS検索ライブラリのLuceneおよびそのサブプロジェクト(Solr/Tika/Mahoutなど)について
(メモ)Crawler Commons Project
http://code.google.com/p/crawler-commons/

バックグラウンド
http://wiki.apache.org/nutch/ApacheConUs2009MeetUp
| 関口宏司 | クローラー | ロボット | スパイダー | 06:49 | comments(0) | trackbacks(0) |
Solr マルチコア コア多すぎ
38,000個のコアを定義したSolrの起動に25分!

https://issues.apache.org/jira/browse/SOLR-1575
| 関口宏司 | Solr | 15:22 | comments(0) | trackbacks(0) |
インデックスの互換性(2.9〜3.0〜4.9)
Lucene 3.0で作成したインデックスはLucene 2.9では読めない。なぜならLucene 2.9でdeprecatedとなったStore.COMPRESSがLucene 3.0では削除され、インデックスのバージョン番号が上がったためである。

従来通りその逆はOKであり、Lucene 2.Xで作成したインデックスはLucene 3.0で検索に使うことができる。また、Lucene 3.0でインデックスを更新すると、新しいセグメントファイルは新フォーマットで作成される。

Lucene 3.0で作成したインデックスは、Lucene 4.9まで使える予定である。Lucene 2.9のインデックスはLucene 4.0になるとサポートされなくなる。

2.9でdeprecatedとなったStore.COMPRESSは、これまで次のように書いていたプログラムを:

doc.add( new Field( "body", bodyString, Store.COMPRESS, Index.ANALYZED ) );


次のようにCompressionToolsを使って書き換えればよい(2行必要になる):

doc.add( new Field( "body", bodyString, Store.NO, Index.ANALYZED ) );
doc.add( new Field( "body", CompressionTools.compressString(bodyString), Store.YES ) );
| 関口宏司 | Luceneインデックス | 09:29 | comments(0) | trackbacks(0) |
着々とJava 5対応中(3.0)
Lucene 3.0はJava 5(Java 1.5)に対応したAPIへの変更を着々と進行中(ほぼ完了):

| 関口宏司 | Luceneリリース | 08:06 | comments(0) | trackbacks(0) |
(メモ)Hadoop 0.20 release tarballのビルド方法
プロパティjava5.homeにJava 5のホームディレクトリ、プロパティforrest.homeにApache Forrestのインストールディレクトリの指定がそれぞれ必要。

$ java -version
java version "1.6.0_15"
Java(TM) SE Runtime Environment (build 1.6.0_15-b03-226)
Java HotSpot(TM) 64-Bit Server VM (build 14.1-b02-92, mixed mode)
$ pwd
/Users/koji/Project/hadoop/common/hadoop
$ ant tar -Djava5.home=/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Home -Dforrest.home=/Users/koji/dev/apache-forrest-0.8
  :
BUILD SUCCESSFUL
Total time: 7 minutes 38 seconds
$ ls build
ant				hadoop-0.20.2-dev-examples.jar
c++				hadoop-0.20.2-dev-test.jar
classes				hadoop-0.20.2-dev-tools.jar
contrib				hadoop-0.20.2-dev.tar.gz
docs				ivy
examples			src
hadoop-0.20.2-dev		test
hadoop-0.20.2-dev-ant.jar	tools
hadoop-0.20.2-dev-core.jar	webapps
| 関口宏司 | Hadoop | 00:30 | comments(0) | trackbacks(0) |
ホワイトペーパー「Solr 1.4の新機能」
Solr 1.4がまもなく公開される。そこで「Solr 1.4の新機能」を紹介したホワイトペーパーを用意した:

http://www.rondhuit.com/download.html

嗚呼、「今週中には公開されます」「次回お会いしたときには公開されていますよ」と何度顧客に堂々と宣言し、嘘をついてしまったことか。結果的にSolr 1.3の公開から1年以上も経ってしまった。Solr 1.3のときもやはり「出る出る」と言いながら実際にリリースされるまでに半年ぐらい経ってしまっていた。

Solr 1.3公開後にコミッター内では「リリースは6ヶ月毎にはやろうよ」「みんなでやろうぜ(TM by 谷垣禎一)」と盛り上がったのは何だったのか、まあいいけど。


Solr 1.4、お待たせしました、間もなく公開です。


受講者アンケートで大好評の「速習 Solr 1.4」受講者募集中!

| 関口宏司 | Solr | 10:40 | comments(1) | trackbacks(0) |
インデックスのサイズを見るシミュレーションプログラム
Luceneのインデックスは検索しながら更新していると、古いインデックスを参照しているSearcherがいる間はセグメントを消すことができない。そのため、大きなマージが走るときはハードディスクの容量を一時的に大量に消費する。

その様子(マージの部分のみ)をシミュレーションする(Luceneを一切使用しない)プログラムを作成した。プログラムを実行するとCSVファイルが出力される。それをEXCELで表示したのが下の図である:

インデックスのサイズ

EXCELで表示できるよう、この図ではマージ係数を3に設定している。プログラムは以下の通りである:

public class MergeSimulator {
  
  static final String CSV_FILE = "segments.csv";
  static final int MERGE_FACTOR = 3;
  static final int MAX_BUFFERED_DOCS = 3;
  static final int NUM_DOCS = 3000;

  public static void main( String[] args ) throws FileNotFoundException {
    Directory dir = new Directory( MERGE_FACTOR );
    PrintStream ps = new PrintStream( CSV_FILE );
    dir.logHeader( ps );
    Writer writer = new Writer( MAX_BUFFERED_DOCS, dir, ps );
    for( int i = 0; i < NUM_DOCS; i++ ){
      writer.add( new Doc() );
    }
    ps.close();
  }

  static class Doc {
  }

  static class Segment {
    private final int level;
    private final int numDocs;
    private boolean deleted;
    public void delete(){ deleted = true; }
    public boolean isDeleted(){ return deleted; }
    public Segment( int numDocs ){
      this( 0, numDocs );
    }
    public Segment( int level, int numDocs ){
      this.level = level;
      this.numDocs = numDocs;
    }
    public int getSize(){ return numDocs; }
    public int getLevel(){ return level; }
  }
  
  static class Directory {
    private final int mergeFactor;
    private List> segmentsList = new ArrayList>();
    public Directory( int mergeFactor ){
      this.mergeFactor = mergeFactor;
    }
    public List> getSegmentsList(){ return segmentsList; }
    public int getNumSegments(){
      int num = 0;
      for( List segments : segmentsList ){
        if( segments == null ) continue;
        for( Segment segment : segments ){
          num++;
        }
      }
      return num;
    }
    public int getSize(){
      int size = 0;
      for( List segments : segmentsList ){
        if( segments == null ) continue;
        for( Segment segment : segments ){
          size += segment.getSize();
        }
      }
      return size;
    }
    public void addSegment( Segment segment ){
      int level = segment.getLevel();
      if( segmentsList.size() <= level )
        segmentsList.add( new ArrayList() );
      List segments = segmentsList.get( level );
      segments.add( segment );
      if( needMerge( level ) )
        merge( level );
    }
    public void merge( int level ){
      List segmentsToBeMerged = segmentsList.get( level );
      int totalDocs = 0;
      for( Segment segment : segmentsToBeMerged ){
        totalDocs += segment.numDocs;
        segment.delete();
      }
      Segment mergedSegment = new Segment( level + 1, totalDocs );
      addSegment( mergedSegment );
    }
    public boolean needMerge( int level ){
      List segments = segmentsList.get( level );
      if( segments == null ) return false;
      return segments.size() >= mergeFactor;
    }
    public void deleteMergedSegments(){
      for( List segments : segmentsList ){
        if( segments == null ) continue;
        for( Iterator ite = segments.iterator(); ite.hasNext(); ){
          Segment segment = ite.next();
          if( segment.isDeleted() ){
            ite.remove();
          }
        }
      }
    }
    public void logHeader( PrintStream ps ){
      ps.println( "number of segments, total size" );
    }
    public void log( PrintStream ps ){
      ps.println( getNumSegments() + ", " + getSize() );
    }
  }
  
  static class Writer {
    final int maxBufferedDocs;
    final Directory dir;
    final PrintStream ps;
    int docs;
    public Writer( int maxBufferedDocs, Directory dir, PrintStream ps ){
      this.maxBufferedDocs = maxBufferedDocs;
      this.dir = dir;
      this.ps = ps;
      docs = 0;
    }
    public void add( Doc doc ){
      if( ++docs >= maxBufferedDocs ){
        Segment segment = new Segment( docs );
        dir.addSegment( segment );
        dir.log( ps );
        dir.deleteMergedSegments();
        docs = 0;
      }
      else{
        dir.log( ps );
      }
    }
  }
}
| 関口宏司 | Luceneインデックス | 12:41 | comments(0) | trackbacks(0) |
setRAMBufferSizeMBの上限を明確化(2.9.1)
Lucene/Solrでヒープの消費に影響するパラメータのひとつであるIndexWriterのsetRAMBufferSizeMB()メソッドに渡す引数に、明確な上限値が設けられた:

https://issues.apache.org/jira/browse/LUCENE-1995

(今回のLUCENE-1995の問題は違うけれども)OutOfMemoryError(OOM)はLucene/Solrコミュニティでも常に話題の上位にランクインしている。繰り返し質問されるのは結局のところ、原理がよく理解できていないのが原因と思われる。インデックスサイズが増えたときにOOMに遭遇し、物理メモリを増やし-Xmxパラメータを増やすことでしのいでいる方は、ぜひ体系的にSolrを学び直すことをお勧めします。;-)


アフターサポート付き「速習 Solr 1.4」受講者募集中!


内容的にあまりに詰め込みすぎたため、年内に閉講するかもしれません。
| 関口宏司 | Luceneクラス解説 | 11:41 | comments(0) | trackbacks(0) |
ホワイトペーパー「Lucene 2.9の新機能」の公開
弊社のダウンロードページホワイトペーパー「Lucene 2.9の新機能」を公開した。
| 関口宏司 | Luceneリリース | 21:16 | comments(0) | trackbacks(0) |
BooleanQueryの不具合修正(2.9.1)
BooleanQueryで検索にヒットするはずのドキュメントが漏れる不具合が先日リリースされたばかりの2.9.0で発覚した。同じテストコードは2.4.1では出ないので、2.9.0で新たに入り込んだバグである。すでに修正され、2.9.1に含まれる。2.9.1にはFastVectorHighlighterの修正も含まれる。

BooleanQueryの不具合
https://issues.apache.org/jira/browse/LUCENE-1974

FastVectorHighlighterの不具合
https://issues.apache.org/jira/browse/LUCENE-1953

Solr 1.4はRCを現在準備中だが、Lucene 2.9.1を取り込む予定である。
| 関口宏司 | 不具合関連 | 10:10 | comments(0) | trackbacks(0) |
+ Solrによるブログ内検索
1234567
891011121314
15161718192021
22232425262728
2930     
<< November 2009 >>
+ LINKS
検索エンジン製品 - 比較のポイント
商用検索エンジンを購入した企業担当者は読まないでください。ショックを受けますから・・・
>>製品比較 10のポイント
+ Lucene&Solrデモ
+ ThinkIT記事
+ RECOMMEND
Lucene in Action
Lucene in Action (JUGEMレビュー »)
Erik Hatcher,Otis Gospodnetic,Mike McCandless
FastVectorHighlighterについて解説記事を寄稿しました。
+ RECOMMEND
+ RECOMMEND
+ SELECTED ENTRIES
+ RECENT COMMENTS
+ RECENT TRACKBACK
+ CATEGORIES
+ ARCHIVES
+ MOBILE
qrcode
+ PROFILE
+ SPONSORED LINKS