Hello,

I work on a web application deployed on a Tomcat server 5. Many jsp front pages 
(thanks to controllers) query a single manager (retrieved by a factory as an 
instance). This manager deals with Lucene index, stored by using a FSDirectory, 
to create several kind of documents, append or remove them from the index and 
so on ... The problem is that many errors often occur when the manager performs 
the index treatment because I don't know how to use the IndewWriter 
efficiently. The main question is : Can I use an single instance of IndexWriter 
(only ONE for the manager that means only one IndexWriter for all the front 
access) ? I guess it's not possible, I got so many times a 
"RAMDirectory.createOutput error". In that way, is it reasonable to create an 
IndexWriter each time the manager need to add a document ? Is there another way 
to proceed ?

I join a complete JUnit test which behaves exactly as my manager. The main 
methods to look at are testIndexManagement (the 
test),getIndexWriter,addDocument,performExactSearchIntoIndex,performApproximativeSearchIntoIndex.

Thank you for your help,

Best regards,

Thomas Legrand
France


/**************************************************************************************/

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.SimpleAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermDocs;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;


public class IndexTest extends TestCase{

    protected static IndexWriter mWriter=null;
    protected static IndexReader mReader=null;
    protected static IndexSearcher mSearcher=null;
    protected static Analyzer mIndexAnalyser=null;
    
    private static  boolean IS_INDEX_LOADED=false;
    private static  String INDEX_LOCATION="indexes//test";
    private static  String ID="ID";
    private static  String CONTENT="content";
    
    public static void main(String[] args) {
        junit.textui.TestRunner.run(suite());
    }

    public IndexTest(String _testName) {
        super(_testName);
        System.out.println("--> "+_testName); 
    }
    
    
    protected void tearDown() throws Exception {
        super.tearDown();
    }
    
    protected void setUp() throws Exception {        
        super.setUp();
        
        /* load index */
        if(IS_INDEX_LOADED){
            System.out.println("\n[setUp] Index already loaded");
        }else{
            System.out.println("\n[setUp] Index loading...");
            loadIndexes();
            IS_INDEX_LOADED=true;
        }
    }


    private Analyzer getIndexAnalyser(){
        System.out.println("\n[getIndexAnalyser][begin]");        
        try{
            if(mIndexAnalyser==null){
                mIndexAnalyser=new SimpleAnalyzer(); 
                System.out.println("[getIndexAnalyser] SimpleAnalyzer created");
            }    
        }catch(Exception analyzex){
            System.out.println("[getIndexAnalyser] Error when creating the 
analyzers: "+analyzex);
            analyzex.printStackTrace();
            fail();            
        }
        System.out.println("[getIndexAnalyser] [end]");
        return mIndexAnalyser;
    }
    
    
    private IndexWriter getIndexWriter(){
        System.out.println("\n[getIndexWriter][begin]");
        Directory indexDir=null;
        
        // Where is the index ?    
        System.out.println("[getIndexWriter] Indexes located in: 
"+INDEX_LOCATION);
        
        // Get the ad's analyser
        Analyzer analyser = getIndexAnalyser(); 
        
        /* create a new writer each time it's required ! */
        if(mWriter==null ){
            try{
                indexDir=FSDirectory.getDirectory(INDEX_LOCATION);
                 
                boolean isTheIndexNew=true;
                mWriter = new IndexWriter(indexDir, analyser, isTheIndexNew);
                System.out.println("[getIndexWriter] Doc index writer created");
            
            }catch(Exception ex){
                System.out.println("[getIndexWriter] Cannot instantiate index 
writer: "+ex);
                ex.printStackTrace();
                fail();
            }
        }else{
            try{
                indexDir=FSDirectory.getDirectory(INDEX_LOCATION);
                 
                boolean isTheIndexNew=true;
                mWriter = new IndexWriter(INDEX_LOCATION, analyser, 
isTheIndexNew);
                System.out.println("[getIndexWriter] Doc index writer created");
            
            }catch(Exception ex){
                System.out.println("[getIndexWriter] Cannot instantiate index 
writer: "+ex);
                ex.printStackTrace();
                fail();
            }
        }
        System.out.println("[getIndexWriter] [end]");
        return mWriter;
    }
    
    
    private IndexReader getIndexReader(){
        System.out.println("\n[getIndexReader][begin]");
        Directory indexDir=null;
        
        // Where is the index ?
        try{
            indexDir=FSDirectory.getDirectory(INDEX_LOCATION);
        }catch(Exception direx){
            System.out.println("[getIndexReader] Error when asserting the 
directory for the index");
            direx.printStackTrace();
            fail();
        }
        System.out.println("[getIndexReader] Indexes located in: 
"+INDEX_LOCATION);
        
        // create the reader if it doesn't exist yet
        if(mReader==null){
            try{
                mReader= IndexReader.open(indexDir); 
                System.out.println("[getIndexReader] User index reader has been 
created");
            
            }catch(Exception ex){
                System.out.println("[getIndexReader] Cannot instantiate index 
reader: "+ex);
                ex.printStackTrace();
                fail();
            }
        }else{                    
            try{
                /* do we need to re-open it ? */
                if(mReader.isCurrent()==false){
                    System.out.println("[getIndexReader] Need to re-open the 
index reader");
                    mReader=IndexReader.open(indexDir);
                }
            }catch(Exception ioex){
                System.out.println("[getIndexReader] Error when re-opening the 
index reader: "+ioex);
                ioex.printStackTrace();
                fail();
            }            
        }
        System.out.println("[getIndexReader][end]");
        return mReader;
    }
    
    
    private IndexSearcher getIndexSearcher(){
        System.out.println("\n[getIndexSearcher] [begin]");

        // create the searcher if it doesn't exist yet
        if(mSearcher==null){
            try{
                mSearcher= new IndexSearcher(getIndexReader()); 
                System.out.println("[getIndexSearcher]The index searcher has 
been created");
            
            }catch(Exception ex){
                System.out.println("[getIndexSearcher] Cannot instantiate index 
searcher: "+ex);
                ex.printStackTrace();
                fail();
            }
        }else{        
            try{
                /* do we need to re-open it ? */
                if(!mSearcher.getIndexReader().isCurrent()){
                    System.out.println("[getIndexSearcher] Need to re-open the 
index searcher (reader)");
                    mSearcher=new IndexSearcher(getIndexReader());
                }
            }catch(Exception ioex){
                System.out.println("[getIndexSearcher] Error when re-opening 
the index searcher: "+ioex);
                ioex.printStackTrace();
                fail();
            }            
        }
        System.out.println("[getIndexSearcher] [end]");
        return mSearcher;
    }
    

    private void addDocument(Document _doc){
        System.out.println("\n[addDocument][begin]");

        try{
            System.out.println("[addDocument] Want to add the doc: 
"+_doc.toString());

            IndexWriter    writer=this.getIndexWriter();

            writer.addDocument(_doc); 
            writer.optimize();
            writer.close();            
            
        }catch(Exception docex){            
            System.out.println("[addDocument] Error when adding the document: 
"+ docex);
            docex.printStackTrace();
            fail();
        }
        System.out.println("[addDocument][end]");
    }
    
    
    private ArrayList<Document> buildDocuments() {
        System.out.println("\n[buildDocuments] [begin]");

        // the result to build 
        ArrayList<Document> documents=null;
        
        try{
            // create the result
            documents= new ArrayList<Document> ();

            Document doc1=new Document();
            doc1.add(new Field(ID,"1", 
Field.Store.YES,Field.Index.UN_TOKENIZED));
            doc1.add(new Field(CONTENT,"test", 
Field.Store.YES,Field.Index.TOKENIZED));
            documents.add(doc1);                        
        
            Document doc2=new Document();
            doc2.add(new Field(ID,"2", 
Field.Store.YES,Field.Index.UN_TOKENIZED));
            doc2.add(new Field(CONTENT,"othertest", 
Field.Store.YES,Field.Index.TOKENIZED));
            documents.add(doc2);    
                
        }catch(Exception ex){            
            System.out.println("[buildDocuments] An error occured while 
building the list of documents: " + ex);
            ex.printStackTrace();
            fail();
        }
        System.out.println("[buildDocuments] [end]");
        return documents;        
    }
    

    private void loadIndexes() throws EncheromaxException{
        
        System.out.println("\n[loadIndexes] [begin]");        
        try{ 
            
            /* build all the documents we need */
            ArrayList<Document> docsToIndex=buildDocuments();
            
            if(docsToIndex==null){
                System.out.println("[oadIndexes] No doc found to index");
            }else{                
                System.out.println("[loadIndexes] Total number of doc to 
index="+docsToIndex.size());
                
                /* create the index now ! */
                Iterator<Document> docIter=docsToIndex.iterator();        
                int total=0;
                while(docIter.hasNext()){
                    Document doc=docIter.next();
                    addDocument(doc);    
                    total++;
                }                    
                System.out.println("[loadIndexes] Total doc indexed="+total);

                System.out.println("[loadIndexes] Indexes successfully 
created");
            }    
            }catch(Exception indexex){
                indexex.printStackTrace();
                fail();
            }    
            System.out.println("[loadIndexes][end]");
    }

    
    protected void appendDocToIndex(String _ID,String _content){        
        System.out.println("\n[appendDocToIndex][begin]");        

        /* that's it */
        try{             
            /* build all the document we need */
            Document doc=new Document();
            doc.add(new Field(ID,_ID, 
Field.Store.YES,Field.Index.UN_TOKENIZED));
            doc.add(new Field(CONTENT,_content, 
Field.Store.YES,Field.Index.TOKENIZED));

            /* write it to the index */
            System.out.println("[appendDocToIndex] Add the document: 
"+doc.toString());
            addDocument(doc);                             
            System.out.println("[appendDocToIndex] Append document 
successfully");
    
            }catch(Exception indexex){                 
                 System.out.println("[appendDocToIndex] Cannot append the doc 
to the index: "+ indexex);
                 indexex.printStackTrace();
                 fail();
            }    
            System.out.println("[appendDocToIndex] [end]");
    }
    
    
    
    protected void removeDocFromIndex(String _ID) throws EncheromaxException{   
     
        System.out.println("\n[removeDocFromIndex][begin]");        
        
        /* first checking */
        if(_ID==null){
            System.out.println("[removeDocFromIndex] No ID provided");
            fail();
        }
        
        /* that's it */
        try{                                 
            // build the term with the ID
            Term iDTerm=new Term(ID,_ID);
            
            // get all the documents that contain the given  ID
            TermDocs docs=getIndexReader().termDocs(iDTerm);
            
            System.out.println("[removeDocFromIndex] Trying to delete a 
document with term: "+iDTerm);        
            int docID=0;
            while(docs.next()){
                docID=docs.doc();
                getIndexReader().deleteDocument(docID);        
                System.out.println("[removeDocFromIndex] Document with 
ID="+docID + " deleted");        
            }
            
            // avoid lock ?
            getIndexReader().close();            
            
            /* check if the document has really been removed */
            TermDocs finalDocs=getIndexReader().termDocs(iDTerm);            
            if(finalDocs.next()){
                System.out.println("[removeDocFromIndex] The document is still 
in the index !");
                //fail();
            }else{
                System.out.println("[removeDocFromIndex] The document has 
really been removed from the index");
            }
            
            
        }catch(Exception indexex){
            System.out.println("[removeDocFromIndex] Cannot remove the document 
from the index: "+ indexex);
            indexex.printStackTrace();
            fail();
        }    
        System.out.println("[removeDocFromIndex][end]");
    }
    
    

    private ArrayList<Document> performExactSearchIntoIndex(String 
_content,String _fieldName) {
        System.out.println("\n[performExactSearchIntoIndex][begin]");    
        ArrayList<Document> documentsFound=null;
        try{            
            // build the term
             Term term=new Term(_fieldName,_content);
                
            //     search now !
            TermDocs docs=getIndexReader().termDocs(term);        
            
            // build the result
            documentsFound=new ArrayList<Document>();    

            int docID=0;
            while(docs.next()){
                docID=docs.doc();
                System.out.println("[performExactSearchIntoIndex] Doc found 
with ID="+docID);                
                Document currentDoc=getIndexReader().document(docID);        
                documentsFound.add(currentDoc); 
            }    
            
        }catch(Exception querex){
            System.out.println("[performExactSearchIntoIndex] Error when 
searching into the doc index: "+ querex);
            querex.printStackTrace();
            fail();
        }
        System.out.println("[performExactSearchIntoIndex][end]");    
        return documentsFound;
    }
    
    
    private ArrayList<Document> performApproximativeSearchIntoIndex(String 
_content,String _fieldName){
        System.out.println("\n[performApproximativeSearchIntoIndex][begin]");   
 
        ArrayList<Document> documentsFound=null;
        
        //     get the searcher        
        IndexSearcher searcher = getIndexSearcher();
        
        try{            
            // build the query
             FuzzyQuery query=new FuzzyQuery(new Term(_fieldName,_content));
                     
            //     search now !
            Hits hits = searcher.search(query);
            System.out.println("[performApproximativeSearchIntoIndex] Total 
result found="+ hits.length());
            
            // build the result
            documentsFound=new ArrayList<Document>();    
            
            int maxAproxHitReturned=hits.length();
            for(int i = 0; i <maxAproxHitReturned; i++){ 
                System.out.println("[performApproximativeSearchIntoIndex] Add a 
document with score="+hits.score(i));
                Document currentDoc = hits.doc(i);                             
                documentsFound.add(currentDoc); 
            }             
        }catch(Exception querex){
            System.out.println("[performApproximativeSearchIntoIndex] Error 
when searching into document in the index: "+ querex);
            querex.printStackTrace();
            fail();
        }
        System.out.println("[performApproximativeSearchIntoIndex][end]");    
        return documentsFound;
    }
    
    
    private ArrayList<Document> searchDocIntoIndex(String[] _search,String[] 
_onfields){
        System.out.println("\n[searchDocIntoIndex] [begin]");    
        ArrayList<Document> docFound=null;
        ArrayList<Document> docFromExactSearch=null;
        ArrayList<Document> docFromApproxSearch=null;    
        HashSet<String> docAlreadyTreatened=null;
        
        if(_search == null || _onfields==null || 
_search.length!=_onfields.length){
            System.out.println("[searchDocIntoIndex] No search field given or 
wrong size");
            fail();
        }
        
        /* ** search a doc by using an exact method (expect only one doc found) 
** */
        for(int i=0;i<_search.length;i++){
            if(_onfields[i].toString()==CONTENT){
                System.out.println("[searchDocIntoIndex] Perform an exact 
search on content: "+_search[i]);    
                docFromExactSearch=performExactSearchIntoIndex(_search[i], 
_onfields[i]);
            }
        }        
        /* build the documents */
        if(docFromExactSearch==null || docFromExactSearch.isEmpty()){
            System.out.println("[searchDocIntoIndex] No doc returned by the 
exact search");    
        }else{
            System.out.println("[searchDocIntoIndex] Total doc returned by the 
exact search (expect 1!) ="+docFromExactSearch.size());    
            // build the result here
            docFound=new ArrayList<Document>();
            // keep the doc found by the exact method to avoid having him twice 
in the final result
            docAlreadyTreatened=new HashSet<String> (docFromExactSearch.size());
            
            for(int i=0;i<docFromExactSearch.size();i++){
                docFound.add(docFromExactSearch.get(i));
                
                // flag the doc ID as treatened
                docAlreadyTreatened.add(docFromExactSearch.get(i).get(ID));
            }
        }
        
        /* ** search a doc by using an approximative  method ** */
        for(int i=0;i<_search.length;i++){
            if(_onfields[i].toString()==CONTENT){
                System.out.println("[searchDocIntoIndex] Perform an 
approximative search on content: "+_search[i]);    
                
docFromApproxSearch=performApproximativeSearchIntoIndex(_search[i], 
_onfields[i]);
            }
        }        
        /* build the documents */
        if(docFromApproxSearch==null || docFromApproxSearch.isEmpty()){
            System.out.println("[searchDocIntoIndex] No doc returned by the 
approximative search");    
        }else{
            System.out.println("[searchDocIntoIndex] Total doc returned by the 
approximative search="+docFromApproxSearch.size());    
            // build the result here
            if(docFound==null)
                docFound=new ArrayList<Document>();
            for(int i=0;i<docFromApproxSearch.size();i++){
                
                if(docAlreadyTreatened!=null && 
!docAlreadyTreatened.contains(docFromApproxSearch.get(i).get(ID))){
                    docFound.add(docFromApproxSearch.get(i));
                }else if(docAlreadyTreatened==null){
                    docFound.add(docFromApproxSearch.get(i));
                }else
                    System.out.println("[searchDocIntoIndex] Doc with 
ID="+docFromApproxSearch.get(i).get(ID) + " already treatened by the exact 
search");    
            }
        }
        System.out.println("[searchDocIntoIndex] [end]");
        return docFound;
    }


    public  static Test suite() {        
        TestSuite testsuite = new TestSuite();
        testsuite.addTest(new IndexTest("testIndexManagement"));        
        return testsuite;
    }    
    
    
    
    public void testIndexManagement(){
        System.out.println("[testIndexManagement][begin]");        
        Date justBefore=new Date();
        long timeBefore=justBefore.getTime();
        
                
        /* make sure we don't already have a new do in the index  */
        System.out.println("\n\n---- Not in the index 
----------------------------------------");
        try{            
            String[] field=new String[1];
            field[0]=CONTENT;
            String[] search=new String[1];
            search[0]="new";
            assertNull(searchDocIntoIndex(search,field));        
            
        } catch (Exception ex){
            ex.printStackTrace();
            fail();
        }        
        
        /* append a new doc to the index  */
        System.out.println("\n\n---- Append doc 
----------------------------------------");
        try{
            appendDocToIndex("3", "new")    ;        
        } catch (Exception ex){
            ex.printStackTrace();
            fail();
        }        
    
        
        /* make sure we have the new doc once in the index */
        System.out.println("\n\n---- Once in the index 
----------------------------------------");
        try{
            String[] field=new String[1];
            field[0]=CONTENT;
            String[] search=new String[1];
            search[0]="new";
            assertEquals(searchDocIntoIndex(search,field).size(),1);        
        } catch (Exception ex){
            ex.printStackTrace();
            fail();
        }    
        
        /* delete the doc */
        System.out.println("\n\n---- Delete the doc 
----------------------------------------");
        try{
            removeDocFromIndex("3");
        } catch (Exception ex){
            ex.printStackTrace();
            fail();
        }    

        
        /* make sure he disappeared from the index */
        System.out.println("\n\n---- Doc dissapeared 
----------------------------------------");
        try{
            String[] field=new String[1];
            field[0]=CONTENT;
            String[] search=new String[1];
            search[0]="new";
            assertNull(searchDocIntoIndex(field,search));        
            
        } catch (Exception ex){
            ex.printStackTrace();
            fail();
        }
        
        
        Date justAfter=new Date();
        long timeAfter=justAfter.getTime();
        System.out.println("[testIndexManagement] Test  performed in " + 
(timeAfter-timeBefore) + " ms");
        System.out.println("[testIndexManagement][end]\n");
    }
}









 
             
---------------------------------
 Ne gardez plus qu'une seule adresse mail ! Copiez vos mails vers Yahoo! Mail 

Reply via email to