9 posts tagged “lucene”
久しぶりにLuceneネタ。
LUCENE-1339が2.4.0から入ったので、IndexReaderのincRef/decRefがpublicになった。これで自前Reference Countしなくて良くなった。
LUCENE-1315(Add setIndexReader in IndexSearcher)も追加されるのかと思ってたけど、どうも入ってないみたい。
IndexWriter.expungeDeletesとか2.4で試したいことがあるけど、他の作業が多すぎる…
気付いたらlucene java 2.3.0が出てた。MLの流量が多くて後で読もうと思ってたら…。dev-javaでRC3のあとアナウンスの準備してたから、もうすぐだとは思ってたけど。いつのまにかhadoopがトップに上がってた。
大きいインデックスでマージ時間が悩ましいとか、indexingのスピードを上げたい人は、試しに使ってみると良いと思う。
あと、IndexReader.reopenとかは便利。
2.4で期待してるもの。
Lucene-1120 Use bulk-byte-copy when merging term vectors
書いてあるとおり、フォーマットが変わるのでしばらく実験で使ってみよう。私の所でも、TermVectorsのファイルはサイズが大きいので効果がありそう。
Lucene-1121 Use nio.transferTo when copying large blocks of bytes
nioを使うので微妙に盛り上がってる。書いてあるとおりCFSを作るのは速くなりそう(CFSは複数のファイルをまとめただけで、まず元ネタを作ってからCFSにまとめるので)。
ただ、CFSを使うと一時的にディスク使用量が2倍(CFSと元ネタ)になるし、IO負荷も高いので今は避けてる(そのせいで、大量のインデックスをマージするときに、ファイル開きすぎではまったりする)
よくみたら、next(Token result)ってAPIが追加されてたのね。
これ使えば問題なかった。
訂正: ちゃんと使えば問題ありません。
何にも考えずに、Tokenizerで1つのTokenだけ保持して使い回すようにしたら、
今まで検索できていたものが検索できなくなった。
queryをrewrite&toStringしてやっと気付いた。気付くまで時間がかかってしまった。
TokenをつかいまわすTokenizer/AnalyzerをQueryParserで使うと、
Analyze結果をPhraseQueryとかにするために、TokenをVectorに入れて保持してるから、
最終的に取得できるQueryでつかうTermが全部同じになってしまう。
気付けば当たり前なんだけど。
Indexの構築は問題なかった。
いつ出るのかわからないけど、かなり性能が改善しているようなので見てみた。
うれしい改善
- Fieldつかいまわし(LUCENE-963)。これでDocumentも使い回せる。
- Tokenつかいまわし(LUCENE-969)。Tokenizer内でTokenを使い回す。
- IndexReader.reopen()(LUCENE-743)。Searcherを作り直さないで良いなら、かなり便利になる気がする。
Field使い回し
フィールドの数だけFiledのインスタンスを作っておいて、Documentにaddしておく。
あとは、実際にインデックスにつっこみたい文書を、作っておいたフィールドにそれぞれ設定して、
IndexWriterにdocをaddすればいい。docに対してaddするのは最初だけで良い。
final Document doc = new Document();
final Field url = new Field("url", "", Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO);
final Field title = new Field("title", "", Field.Store.NO, Field.Index.TOKENIZED, Field.TermVector.NO);
final Field desc = new Field("desc", "", Field.Store.NO, Field.Index.TOKENIZED, Field.TermVector.NO);
doc.add(url); doc.add(title); doc.add(desc);
for (Content c: clist) {
url.setValue(c.url);
title.setValue(c.title);
desc.setValue(c.desc);
indexWriter.add(doc);
}
Token使い回し
Tokenをコンストラクタで作っておいて、nextが呼ばれるたびにTokenに設定されている値を変えるだけ。Termを書き換えるのに、termBufferを書き換えた方が良いようなのでそうしてみる。
まだベンチマークしてないから、どれだけ効果あるのか不明。
final int len = term.length();
char[] buf = token.termBuffer();
if (buf.length < len) {
buf = token.resizeTermBuffer(len);
}
term.getChars(0, len, buf, 0);
token.setTermLength(len);
python+cmecabを使って、chasen server(chasend?)もどきを書きました。
LuceneでJapaneseAnalyzer+ChasenTokenizerで使う事しか考えてないけど、とりあえず使える。
いまいち仕様がわからないので、ChasenTokenizerのソースとmecab -Ochasenの出力を見て書いてみた。
Lucene-jaに含まれている、NormalizeReaderのCONVERSION_TABLEの、二つめの'+'は'='の間違いかな?