收录日期:2019/10/18 22:56:39 时间:2009-11-11 00:49:34 标签:java,lucene

Background

I am assuming the following code is completely thread safe:

// Called from a servlet when a user action results in the index needing to be updated
public static void rebuildIndex() {
FSDirectory dir = new NIOFSDirectory(new File(Configuration.getAttachmentFolder()), null);
IndexWriter w = new IndexWriter(dir, analyzer, IndexWriter.MaxFieldLength.UNLIMITED);
.... build index ...
w.optimize();
w.commit();
w.close();
}

The following code is called from the search servlet:

// Called by the search servlet
public void search() {
FSDirectory dir = new NIOFSDirectory(new File(Configuration.getAttachmentFolder()), null);
IndexReader indexReader = IndexReader.open(dir,true);
IndexSearcher searcher = new IndexSearcher(indexReader);
.... do the search ...
}

Questions

I am trying to work out the best/correct way to implement this to avoid multi-threading problems:

  1. Should the FSDirectory dir object be shared as some sort of static variable?
  2. Should the IndexSearcher searcher or the IndexReader indexReader objects be stored as a static variable, and then simply replaced when the index is rebuilt?

You should just move indexReader and searcher to the end of rebuildIndex() and of course synchronize on searcher in rebuildIndex() and in search(). But based on how often index has to be rebuilt and how quick search results have to be returned, you might have to consider some caching of indexReader and searcher rather than search threads waiting everytime index is being rebuilt.

Opening new IndexSearcher and IndexReader whenever somebody executes a search is very inefficient. Best to have a single reader that is shared by all calls to search(). This reader instance is closed and replaced whenever you need to rebuild the index. Of course, this will need to be synchronized. This is elaborated more at:

http://wiki.apache.org/lucene-java/UpdatingAnIndex