関口宏司のLuceneブログ

OSS検索ライブラリのLuceneおよびそのサブプロジェクト(Solr/Tika/Mahoutなど)について
(メモ)ElasticSearch
Luceneを使って作られた、JSON over HTTPで登録/検索できる検索エンジン:

ElasticSearch
http://www.elasticsearch.com/products/elasticsearch/

curl -XPUTで登録し、curl -XGETで検索している様子をビデオデモで見られる
| 関口宏司 | Luceneツール | 08:21 | comments(0) | trackbacks(0) |
Lucene 3.1以降ではAnalyzerにLuceneのバージョンを渡す件
Lucene 3.1以降ではほとんどのAnalyzerのコンストラクタがVersion(Enum)を引数に取るので、ユーザは使用するLuceneのバージョンを渡さなければいけない。MLにAnalyzerを作成するときのパターンが載っていたので転記する:

final Analyzer createAnalyzer(String className, Version matchVersion) throws Exception {
  final Class clazz = Class.forName(className).asSubclass(Analyzer.class);
  try {
    // first try to use a ctor with version parameter (needed for many new Analyzers that have no default one anymore
    return clazz.getConstructor(Version.class).newInstance(matchVersion);
  } catch (NoSuchMethodException nsme) {
    // otherwise use default ctor
    return clazz.newInstance();
  }
}


ネタもと:
http://old.nabble.com/Having-a-default-constructor-in-Analyzers-td27490616.html
| 関口宏司 | Luceneクラス解説 | 09:19 | comments(0) | trackbacks(0) |
@lucene.experimental と @lucene.internal Javadocタグ
これまで書き方が統一されていなかったLucene Javadocにおける試験的なAPIと内部使用目的のAPIのWARNINGメッセージが、AntのJavadocタスクの機能(javadocコマンドの-tagオプション)を使って統一された。試験的なAPIとは、publicなクラスやメソッドであっても、「これは試験的なAPIであり、将来互換性を保たない方法で変更される恐れがあります」といった統一されたWARNINGメッセージがJavadocに表示される。またLucene内部使用目的のAPIも類似のメッセージが表示される:

https://issues.apache.org/jira/browse/LUCENE-2209
| 関口宏司 | Luceneクラス解説 | 09:36 | comments(0) | trackbacks(0) |
ヒープ消費量を計算するクラス(2.9)
LUCENE-1749の一部としてヒープの消費量を計算するユーティリティクラスRamUsageEstimatorがLucene 2.9に追加されたのでその使い方を紹介しよう。簡単なのでいきなりサンプルプログラムを示す:

public class TestRamUsage {

  private final String name;
  private TestRamUsage tru;
  
  public TestRamUsage( String name ){
    this.name = name;
  }
  
  public static void main(String[] args) {
    RamUsageEstimator rue = new RamUsageEstimator();

    TestRamUsage mike = new TestRamUsage( "Mike" );
    System.out.println( "size of mike = " + rue.estimateRamUsage( mike ) );

    TestRamUsage christian = new TestRamUsage( "Christian" );
    System.out.println( "size of christian = " + rue.estimateRamUsage( christian ) );
    
    mike.tru = christian;
    System.out.println( "size of mike = " + rue.estimateRamUsage( mike ) );
  }

}


これを実行すると、次のように表示される:

size of mike = 16
size of christian = 16
size of mike = 32


2回目の"mike"のサイズが2倍になっているのは、mikeのメンバ変数にchristianを代入したためである。このようにRamUsageEstimatorはオブジェクトのツリーをたどってそのオブジェクトの全消費量を示してくれる。

なお、"mike"と"christian"でnameの長さが違うのに同じサイズになっているのは、オブジェクトがStringの場合、デフォルトでintern()したものと比較し、オブジェクトとintern()したものの参照が同じならばサイズとして算入しないようになっているためである。この動作を変えるには、RamUsageEstimatorのコンストラクタにfalseを渡してやればよい。すると、実行結果は次のようになる:

size of mike = 64
size of christian = 74
size of mike = 138
| 関口宏司 | Luceneクラス解説 | 07:02 | comments(0) | trackbacks(0) |
(メモ)Antiword
http://www.winfield.demon.nl/

Wordファイルからテキストデータを抽出するツール。対応プラットフォームが充実しており、VMS、Zaurus、BeOSまでをもサポートしている。
| 関口宏司 | Luceneツール | 08:23 | comments(1) | trackbacks(0) |
THIS IS IT
"THIS IS IT"といえばマイケル・ジャクソンの映画として有名だが、我々検索業界関係者の間では「ストップワードだけからなる文書」として2009年にたびたびとりあげられた格好のサンプルデータとなったものである。

ところで映画/DVDなどのタイトルには、このようにストップワードが重要な要素となっているものが少なくなく、単純にStopFilterを適用するわけにはいかない場合がある。そんなときはStopFilterをとりあえず適用しないという手もあるが、そうすると"the", "a", "it"などを含む文書は数が多く、そこから今度はユーザクエリのフレーズにマッチしない文書を取り除くのにコストがかかってしまう。

このような場合に便利なのがShingleFilterである。"shingle"とはワード単位のN-gramのことで、"THIS IS IT"に2-gramのShingleFilterを適用すると、"THIS IS", "IS IT"というトークンを出力してくれるため、単独のトークンよりもdocFreqが小さく抑えられ、性能を維持しつつタイトルを検索できるようになる。
| 関口宏司 | Luceneクラス解説 | 11:08 | comments(0) | trackbacks(0) |
IndexableBinaryStringTools (2.9)
Luceneは当初からバイナリデータをインデックスに登録できたが、それは単にバイナリデータを出し入れするだけであり、バイナリデータを検索の対象にするものではなかった。

Lucene 2.9で追加されたIndexableBinaryStringToolsクラスを使うとバイナリデータ(byte[])をソートオーダーを維持したまま、インデックスに索引付けできるStringに変換できる。これにより、バイナリデータも検索できるようになった。もっともこのクラスが導入された動機は、ロケールに依存したトークンのソートを行うためにCollatorを使った場合、さらにソートの高速化のためにCollationKeyによって変換されたバイナリデータを索引付けしたいがためのものである。

関連JIRA:

IndexableBinaryStringToolsクラスの導入
https://issues.apache.org/jira/browse/LUCENE-1434

トークンをCollationKeyで変換、IndexableBinaryStringToolsでエンコードするCollationKeyFilterの導入
https://issues.apache.org/jira/browse/LUCENE-1435

Lucene 2.9ではCollationKeyFilterはcontrib/collationの下にJDKのCollatorを使った実装と、ICUのものを使った実装が同居していたが、現在開発中のLucene 3.1ではJDKのものをLucene coreに移動し、ICUライブラリに依存する実装はcontrib/icuというディレクトリが新設されてそこに移動された。これにともない、contrib/collationディレクトリは廃止された:

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

このような背景のIndexableBinaryStringToolsではあるが、あえてバイナリデータを登録(索引付け)し、検索してみると、次のようなプログラムになる:

public class TestIndexableBinaryStringTools {

  static Directory dir = new RAMDirectory();
  static Analyzer analyzer = new WhitespaceAnalyzer();
  
  public static void main(String[] args) throws IOException {
    makeIndex();
    searchIndex();
  }

  static void makeIndex() throws IOException {
    IndexWriter writer = new IndexWriter( dir, analyzer, true, MaxFieldLength.LIMITED );
    for( int i = 0; i < 3; i++ ){
      Document doc = new Document();
      doc.add( new Field( "id", Integer.toString( i ), Store.YES, Index.ANALYZED ) );
      doc.add( new Field( "data", bytes2String( new byte[]{ (byte)i } ), Store.YES, Index.NOT_ANALYZED ) );
      writer.addDocument( doc );
    }
    writer.close();
  }
  
  static String bytes2String( byte[] data ){
    CharBuffer charBuffer = IndexableBinaryStringTools.encode( ByteBuffer.wrap( data ) );
    return new String( charBuffer.array() );
  }
  
  static void searchIndex() throws IOException {
    IndexSearcher searcher = new IndexSearcher( dir );
    Query query = new TermQuery( new Term( "data", bytes2String( new byte[]{ 2 }) ) );
    TopDocs docs = searcher.search( query, 10 );
    for( ScoreDoc scoreDoc : docs.scoreDocs ){
      Document doc = searcher.doc( scoreDoc.doc );
      System.out.println( "id = " + doc.get( "id" ) );
      System.out.println( "data = " + string2Bytes( doc.get( "data" ) )[0] );
    }
    searcher.close();
  }
  
  static byte[] string2Bytes( String s ){
    ByteBuffer byteBuffer = IndexableBinaryStringTools.decode( CharBuffer.wrap( s.toCharArray() ) );
    return byteBuffer.array();
  }
}
| 関口宏司 | Luceneクラス解説 | 14:20 | comments(0) | trackbacks(0) |
(メモ)Free live video streaming of ApacheCon US 2009
http://streaming.linux-magazin.de/en/program-apachecon-us-2009.htm
| 関口宏司 | Luceneセミナー | 00:24 | comments(0) | trackbacks(0) |
Solr SVNリポジトリにクラウドブランチ登場!
http://svn.apache.org/viewvc?view=revision&revision=888480
| 関口宏司 | Solr | 09:17 | comments(0) | trackbacks(0) |
(検索)APIの後方互換性チェックテストコード
Luceneのテストコードは通常JUnitを使って書かれた単体テストになっているが、検索パッケージには"JustCompile"というファイル名で始まる「APIの後方互換性をチェックするためだけの実行されないテストコード」がある:

$ find . -name JustCompile¥*.java
./test/org/apache/lucene/search/function/JustCompileSearchSpans.java
./test/org/apache/lucene/search/JustCompileSearch.java
./test/org/apache/lucene/search/spans/JustCompileSearchSpans.java


"JustCompile"テストコードはそれぞれのパッケージのpublicインタフェースおよび抽象クラスをimplementsまたはextendsした具象クラスを用意している。このしくみにより、将来、インタフェースに新しいメソッドや抽象クラスに新しい抽象メソッドがうっかり加えられると、コンパイルエラーになることで警告できるようにしている。
| 関口宏司 | Luceneクラス解説 | 23:59 | comments(0) | trackbacks(0) |
+ Solrによるブログ内検索
+ PROFILE
 123456
78910111213
14151617181920
21222324252627
28      
<< February 2010 >>
+ 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
+ SPONSORED LINKS