2014年07月19日

Luceneに32bit以上の数のデータを入れてみる

Luceneの検索件数を返すtotalHitsがintだったので32bit以上だとどうなるんだろうと思ってやってみた。 書いたコード。

import java.io.File

import org.apache.lucene.analysis.core.WhitespaceAnalyzer
import org.apache.lucene.document.Document
import org.apache.lucene.document.Field
import org.apache.lucene.index.DirectoryReader
import org.apache.lucene.index.IndexWriter
import org.apache.lucene.index.IndexWriterConfig
import org.apache.lucene.search.IndexSearcher
import org.apache.lucene.search.MatchAllDocsQuery
import org.apache.lucene.store.FSDirectory
import org.apache.lucene.store.SimpleFSDirectory
import org.apache.lucene.util.Version

class Foo extends App {
  def createIndex() {
    val dir = new SimpleFSDirectory(new File("index"))
    val config = new IndexWriterConfig(Version.LUCENE_4_9, new   WhitespaceAnalyzer(Version.LUCENE_4_9))
    val writer = new IndexWriter(dir, config)

    var i = 0L
    while (i < Integer.MAX_VALUE.toLong + 1000) {
      val doc = new Document()
      doc.add(new Field("id", (i % 1000).toString, Field.Store.NO, Field.Index.ANALYZED))
      writer.addDocument(doc)
    }

    writer.close()
  }
}

Integer.MAX_VALUE.toLong + 1000までドキュメント書き込みまくれと命令している。

結果はまあそうだよなぁという感じで、先にソースコード見た方が早いだろうという結果。

Exception in thread "main" java.lang.IllegalArgumentException: Too many documents, composite IndexReaders cannot exceed 2147483647

ちなみにsolrjのgetNumFoundはlongになっている。普通に考えて1個のLuceneのsegmentが2億もデータを持ったりはしないだろうから、分散してそれ以上になるようなパターンではsolrなりelastic searchなりで取りまとめてもらえば問題ないわけか。