Lucene の新しい 4.4.0 リリースでは、Near Real Time Manager (org.apache.lucene.search.NRTManage) がControlledRealTimeReopenThreadに置き換えられました。
新しい ControlledRealTimeReopenThread の使用法に関するサンプル コードはありますか?
編集:私は以下の私自身の質問に答えます
Lucene の新しい 4.4.0 リリースでは、Near Real Time Manager (org.apache.lucene.search.NRTManage) がControlledRealTimeReopenThreadに置き換えられました。
新しい ControlledRealTimeReopenThread の使用法に関するサンプル コードはありますか?
編集:私は以下の私自身の質問に答えます
すべてのドキュメントの後にコミットするべきではなく、再オープン スレッドを Thread.interrupt する必要もありません (実際、NIOFSDirectory を使用している場合、これは致命的です)。代わりに、その (ControlledRealTimeReopenThread) close メソッドを呼び出すだけです。フードの下で、それ自体に通知し、すぐに終了する必要があります。
「commit」は保留中のすべてのデータをディスクにフラッシュします。commit を使用する場合は、ControlledRealTimeThread を使用する必要はありません。ControlledRealTimeThread は、書き込み操作と読み取り操作をリアルタイムで調整します。
ドキュメントを追加する場合: ReferenceManager.maybeRefresh()
検索操作の場合: ReferenceManager.acquire()、op..、ReferenceManager.acquire()
テストコード
package kr.nsri.lucene440;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.index.TrackingIndexWriter;
import org.apache.lucene.search.ControlledRealTimeReopenThread;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.ReferenceManager;
import org.apache.lucene.search.SearcherManager;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
public class AddRandom {
public static void main(String[] args) throws IOException,
InterruptedException {
// Basic Environment
FSDirectory dir = FSDirectory
.open(new File("/Users/inseog/tmp/lu440/"));
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_44);
IndexWriterConfig indexWriterConfig = new IndexWriterConfig(
Version.LUCENE_44, analyzer);
indexWriterConfig.setOpenMode(OpenMode.CREATE_OR_APPEND);
IndexWriter indexWriter = new IndexWriter(dir, indexWriterConfig);
// Real time handler
TrackingIndexWriter trackingIndexWriter = new TrackingIndexWriter(
indexWriter);
ReferenceManager<IndexSearcher> searcherManager = new SearcherManager(
indexWriter, false, null);
// thread handling
ControlledRealTimeReopenThread<IndexSearcher> writeControlThread = new ControlledRealTimeReopenThread<IndexSearcher>(
trackingIndexWriter, searcherManager, 1.0, 0.1);
writeControlThread.setName("Update Reopen Thread");
writeControlThread.setPriority(Math.min(Thread.currentThread()
.getPriority() + 2, Thread.MAX_PRIORITY));
writeControlThread.setDaemon(true);
writeControlThread.start();
// start writer and reader, and wait 10 minutes
WriteDoc wdoc = new WriteDoc(trackingIndexWriter, searcherManager);
ReadDoc rdoc = new ReadDoc(searcherManager);
ExecutorService exman = Executors.newFixedThreadPool(5);
exman.submit(wdoc);
exman.submit(rdoc);
Thread.sleep(1L * 60L * 1000L);
exman.shutdown();
exman.awaitTermination(5, TimeUnit.SECONDS);
System.out.println("Closing...");
writeControlThread.close();
searcherManager.close();
indexWriter.close();
dir.close();
}
}
package kr.nsri.lucene440;
import java.util.Calendar;
import java.util.Random;
import java.util.concurrent.Callable;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ReferenceManager;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.util.Version;
public class ReadDoc implements Callable<Long> {
private ReferenceManager<IndexSearcher> searcherManager;
private final Random rand = new Random(Calendar.getInstance()
.getTimeInMillis());
private Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_44);
private QueryParser parser = new QueryParser(Version.LUCENE_44, "content",
analyzer);
public ReadDoc(ReferenceManager<IndexSearcher> searchManager) {
this.searcherManager = searchManager;
}
@Override
public Long call() {
while (true) {
try {
if (Thread.interrupted())
break;
//
// get index searcher from searcherManager
//
IndexSearcher wsrch = searcherManager.acquire();
//
// read current status
//
System.out.println("------------------ total count: "
+ wsrch.collectionStatistics("content").docCount());
Query query = parser.parse("abcde");
TopDocs topDocs = wsrch.search(query, null, 2000);
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
for (ScoreDoc sd : scoreDocs) {
Document wd = wsrch.doc(sd.doc);
System.out.println("\tRead: " + wd.get("content"));
}
//
// release index searcher for reopen handling
//
searcherManager.release(wsrch);
//
// random wait
//
if (Thread.interrupted())
break;
Thread.sleep(rand.nextInt(15000));
} catch (Exception e) {
break;
}
}
return 0L;
}
}
package kr.nsri.lucene440;
import java.io.IOException;
import java.util.Calendar;
import java.util.Random;
import java.util.concurrent.Callable;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.LongField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.index.TrackingIndexWriter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.ReferenceManager;
public class WriteDoc implements Callable<Long> {
private TrackingIndexWriter trackingIndexWriter;
private ReferenceManager<IndexSearcher> searcherManager;
private final Random rand = new Random(Calendar.getInstance()
.getTimeInMillis());
public WriteDoc(TrackingIndexWriter trackingIndexWriter,
ReferenceManager<IndexSearcher> searcherManager) {
this.trackingIndexWriter = trackingIndexWriter;
this.searcherManager = searcherManager;
}
@Override
public Long call() {
Long wcnt = 0L;
while (true) {
if (Thread.interrupted())
break;
Document doc = new Document();
Long tweetID = rand.nextLong();
String userName = anyWord();
String content = anySentence();
doc.add(new LongField("tweetID", tweetID, Store.YES));
doc.add(new StringField("userScreenname", userName, Store.YES));
doc.add(new TextField("content", content, Store.YES));
try {
//
// add document
//
trackingIndexWriter.addDocument(doc);
System.out.println("\t"+"new doc: "+content);
//
// signal searcher may be reopen to include new document
//
searcherManager.maybeRefresh();
//
// random wait
//
++wcnt;
if (Thread.interrupted())
break;
Thread.sleep(rand.nextInt(15000));
} catch (IOException | InterruptedException e) {
break;
}
}
return wcnt;
}
private String anyWord() {
String r = "";
String base = "abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int wordLen = 1 + rand.nextInt(9);
int baseLen = base.length();
for (int wx = 0; wx < (1 + wordLen); ++wx)
r += base.charAt(rand.nextInt(baseLen));
return r;
}
private String anySentence() {
String r = "";
int wordCount = 1 + rand.nextInt(20);
for (int wx = 0; wx < wordCount; ++wx)
r += anyWord() + " ";
return r + "abcde";
}
}