views:

301

answers:

2

Summary: I collect the doc ids of all hits for a given search by using a custom Collector (it populates a BitSet with the ids). The searching and getting doc ids are quite fast according to my needs but when it comes to actually fetching the documents from disk, things get very slow. Is there a way to optimize Lucene for faster document collection?

Details: I'm working on a processed corpus of Wikipedia and I keep each sentence as a separate document. When I search for "computer", I get all sentences containing the term computer. Currently, searching the corpus and getting all document ids work in sub-second but fetching the first 1000 documents takes around 20 seconds. Fetching all documents takes proportionally more time (i.e. another 20 sec for each 1000 batch).

Subsequent searches and document fetching takes much more little time (though I don't know who's doing the caching, OS or Lucene?) but I'll be searching for many diverse terms and I don't want to rely on caching, the performance on the very first search is crucial for me.

I'm looking for suggestions/tricks that will improve the document-fetching performance (if it's possible at all). Thanks in advance!

Addendum:

I use Lucene 3.0.0 but I use Jython to drive Lucene classes. Which means, I call the get_doc method of the following Jython class for every doc id I retrieved during the search:

class DocumentFetcher():  
  def __init__(self, index_name):  
    self._directory = FSDirectory.open(java.io.File(index_name))  
    self._index_reader = IndexReader.open(self._directory, True)  
  def get_doc(self, doc_id):  
    return self._index_reader.document(doc_id)  

I have 50M documents in my index.

+1  A: 

You, probably, are storing lot of information in the document. Reduce the stored fields to as much as you can.

Secondly, while retrieving fields, select only those fields which you need. You can use following method of IndexReader to specify only few of the stored fields.

public abstract Document document(int n, FieldSelector fieldSelector)

This way you don't load up fields which are not used.

You can utilize following code sample.

FieldSelector idFieldSelector = 
new SetBasedFieldSelector(Collections.singleton("idFieldName"), Collections.emptySet());
for (int i: resultDocIDs) {
String id = reader.document(i, idFieldSelector).get("idFieldName");
}
Shashikant Kore
Thanks for the suggestion and the code sample. I hadn't known about FieldSelector, it could be of use in the future.But, I store only one field in the document and that's what I have to fetch in the end. The only field I store is just the sentence itself plus a few grammatical annotations. That means for a single document (i.e. sentence) I don't store more than 300-400 bytes.(Additional info: I have indexed around 50M documents)
Amaç Herdağdelen
+1  A: 

Scaling Lucene and Solr discusses many ways to improve Lucene performance. As you are working on Lucene search within Wikipedia, you may be interested in Rainman's Lucene Search of Wikipedia. He mostly discusses algorithms and less performance, but this may still be relevant.

Yuval F