17

I am new to Java and Lucene. My code gets a line from a file and stores it in Lucene Index. But when I create an IndexReader to search and read from the index it throws an exception.

My java code is below. On creating the IndexReader it throws an IndexNotFoundException

static String itemsfreq[];
static StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_35);
static IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_35, analyzer);

public static void index_data(Directory indexed_document,int doc_num,IndexWriter w) throws IOException
    {
    for(int i = 0;i < itemsfreq.length;i++)
        {
        Document doc = new Document();
        doc.add(new Field(Integer.toString(doc_num)+","+itemsfreq[i],itemsfreq[i++], Field.Store.YES, Field.Index.ANALYZED));
        w.addDocument(doc);
        }
    }
//Gets string from a file and insert it in INDEX named indexed_document
public static void main(String[] args) throws IOException
    {
    BufferedReader reader = new BufferedReader(new FileReader("fullText100.txt"));
    String line;
    int i = 0;
    Directory indexed_document = new RAMDirectory();
    IndexWriter writer = new IndexWriter(indexed_document, config);
    while((line=reader.readLine()) != null)
        {
        if(i == 1)
            {
            break;
            }
        itemsfreq = line.split(" ");
        index_data(indexed_document,i,writer);
        i++;
        }

    IndexReader r = IndexReader.open(indexed_document);
    } 
Leigh
  • 28,765
  • 10
  • 55
  • 103
Ahmed Khakwani
  • 410
  • 2
  • 8
  • 18

4 Answers4

33

before open the index by using a reader, call once writer.commit()

Lucifer
  • 29,392
  • 25
  • 90
  • 143
YJiao
  • 409
  • 4
  • 6
  • 1
    I was facing similar issue, and using `writer.commit()` fixed it. If I had used `writer.close()`, I would have to re-open the writer again. Your suggestion is better than the previous one. – tuxdna May 06 '13 at 06:35
  • 4
    Indeed, this is the right solution as it is recommended by Lucene docs to re-use single instances of IndexWriter and IndexReader; This way I'm not forced to closw writer and create it again when needed. – Sergiy Sokolenko Apr 01 '15 at 13:48
19

In order to write the changes to the Index you have to close the index writer and then open the IndexReader.

writer.close();

If you have to open the IndexReader before writing is completed, you have to tell the IndexReader to reopen the index in order to see the changes.

csupnig
  • 3,327
  • 1
  • 24
  • 22
9

You need to do is to explicitly call commit before opening your IndexSearcher.

    directory = new RAMDirectory();
    iwriter = new IndexWriter(directory, config);
    iwriter.commit();

Now Open Searcher

ireader = DirectoryReader.open(directory);
isearcher = new IndexSearcher(ireader);

Also remember you need to call commit after adding documents otherwise search may not find it. Searcher needs to reopened after commit (of course close old searcher).

iwriter.commit();
1

I got this error (in Lucene.Net, C#) because I had created an index by creating the appropriate directory on my filesystem and FSDirectory in memory, but hadn't actually added any documents yet.

Specifically, the code to add new documents was checking to make sure that it wasn't adding a duplicate with a reader, but the exception was thrown when trying to add the first document, because there were no segments yet.

I dealt with this like so:

// Make a reader to check the index for duplicates
// The reader will only be aware of items that were in the index before it was created
IndexReader reader = null;
try {
    reader = IndexReader.Open( index, true );
} catch( IOException ) {
    // There is no segments file because the index is empty
    reader = null;
}

... // inside a method called by that scope, with reader passed in

// See if it exists already
// If the reader is null, then the index is empty
if( reader != null ) {
    var existsTerm = new Term( SingleFieldIndexManager.FieldName, formattedTerm );
    var matches = reader.TermDocs( existsTerm );
    if( matches.Next() ) {
        // It's already in there, no need to add again
        return;
    }
}

... // back to the first method after a return

// dispose of the reader if we managed to create one
if( reader != null ) {
    reader.Dispose();
}
DCShannon
  • 2,470
  • 4
  • 19
  • 32
  • 1
    Hey, I am having the same problem as you. But I don't understand how you solved it. If there are no files then it enters the catch block and that's it, right? – Valentin May 07 '15 at 18:17
  • Found the problem. I got this error on creating the IndexWriter with parameter create = false – Valentin May 07 '15 at 18:36
  • Lucent.NET 4.8 (I'm using version 4.8.0-beta00006) uses class `IndexWriterConfig` instead which in turn has a property `OpenMode` which also allows specifying something like `CREATE` or `CREATE_OR_APPEND`. My expectation was that it'd create the index for me, but it appears to ignore that parameter. It's very well possible that I'm not using it correctly just yet. I used 3.0.3 previously, which was able to handle the case when an index was empty. – Manfred Oct 12 '19 at 03:56