Lucene Java ouvre trop de fichiers. Est-ce que j'utilise IndexWriter correctement?


Mon implémentation Lucene Java consomme trop de fichiers. J'ai suivi les instructions dans le Wiki Lucene sur trop de fichiers ouverts, mais cela n'a fait que ralentir le problème. Voici mon code pour ajouter des objets (PTicket) à l'index:

//This gets called when the bean is instantiated
public void initializeIndex() {
    analyzer = new WhitespaceAnalyzer(Version.LUCENE_32);
    config = new IndexWriterConfig(Version.LUCENE_32, analyzer);

}


public void addAllToIndex(Collection<PTicket> records) {  
    IndexWriter indexWriter = null;
    config = new IndexWriterConfig(Version.LUCENE_32, analyzer);

    try{
        indexWriter = new IndexWriter(directory, config);
        for(PTicket record : records) {
            Document doc = new Document();
            StringBuffer documentText = new StringBuffer();
            doc.add(new Field("_id", record.getIdAsString(), Field.Store.YES, Field.Index.ANALYZED));
            doc.add(new Field("_type", record.getType(), Field.Store.YES, Field.Index.ANALYZED));

            for(String key : record.getProps().keySet()) {
                List<String> vals = record.getProps().get(key);

                for(String val : vals) {
                    addToDocument(doc, key, val);
                    documentText.append(val).append(" ");
                }
            }
            addToDocument(doc, DOC_TEXT, documentText.toString());        
            indexWriter.addDocument(doc);    
        }

        indexWriter.optimize();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        cleanup(indexWriter);
    }
}

private void cleanup(IndexWriter iw) {
    if(iw == null) {
        return;
    }

    try{
        iw.close();
    } catch (IOException ioe) {
        logger.error("Error trying to close index writer");
        logger.error("{}", ioe.getClass().getName());
        logger.error("{}", ioe.getMessage());
    }
}

private void addToDocument(Document doc, String field, String value) {
    doc.add(new Field(field, value, Field.Store.YES, Field.Index.ANALYZED));
}

MODIFIER POUR AJOUTER du code pour la recherche

public Set<Object> searchIndex(AthenaSearch search) {  

    try {
        Query q = new QueryParser(Version.LUCENE_32, DOC_TEXT, analyzer).parse(query);

        //search is actually instantiated in initialization.  Lucene recommends this.
        //IndexSearcher searcher = new IndexSearcher(directory, true);
        TopDocs topDocs = searcher.search(q, numResults);
        ScoreDoc[] hits = topDocs.scoreDocs;
        for(int i=start;i<hits.length;++i) {
            int docId = hits[i].doc;
            Document d = searcher.doc(docId);
            ids.add(d.get("_id"));
        }
        return ids;
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

Ce code se trouve dans une application Web.

1) Est-ce la façon conseillée d'utiliser IndexWriter (instancier un nouveau sur chaque ajout à l'index)?

2) j'ai lu que la sensibilisation de l'espace cela aidera, mais cela semble juste être un pansement qui ne résoudra pas le problème réel.

3) Le problème pourrait-il résider avec IndexSearcher?

Author: gmoore, 2011-06-19

4 answers

1) Est-ce la façon conseillée d'utiliser IndexWriter (instancier un nouveau sur chaque ajouter à l'index)?

Je conseille Non, il y a constructeurs, qui vérifiera s'il existe ou créera un nouvel écrivain, dans le répertoire contenant l'index. problème 2 serait résolu si vous réutilisez le indexwriter.

MODIFIER:

Ok il semble que dans Lucene 3.2 le plus mais un constructeur soit obsolète, donc la resue d'Indexwriter peut être obtenue en utilisant Enum IndexWriterConfig.OpenMode avec la valeur CREATE_OR_APPEND .

De plus, l'ouverture d'un nouvel écrivain et la fermeture de chaque document ajouté n'est pas efficace, je suggère de réutiliser, si vous voulez accélérer l'indexation, définissez la valeur par défaut setRamBufferSize est de 16 Mo, alors faites-le par méthode d'essais et d'erreurs

De la documentation:

Notez que vous pouvez ouvrir un index avec create = true même si les lecteurs sont à l'aide de l'index. Les vieux lecteurs continuer à rechercher le "point dans le temps" instantané qu'ils avaient ouvert, et ne pas voir l'index nouvellement créé jusqu'à ce qu'ils ré-ouvert.

Réutilisez également l'IndexSearcher, je ne peux pas voir le code pour la recherche, mais Indexsearcher est threadsafe et peut être utilisé comme En lecture seule aussi bien

Je vous suggère également d'utiliser MergeFactor sur writer, ce n'est pas nécessaire mais aidera à limiter la création de fichiers d'index inversés, faites-le par méthode d'essais et d'erreurs

 3
Author: Narayan, 2011-06-22 11:45:22

Je pense que nous aurions besoin de voir votre code de recherche pour être sûr, mais je soupçonne que c'est un problème avec le chercheur d'index. Plus précisément, assurez-vous que votre lecteur d'index est correctement fermé lorsque vous en avez terminé.

Bonne chance,

 1
Author: Adrian Conlon, 2011-06-19 16:47:04

La réponse scientifique correcte serait: Vous ne pouvez pas vraiment dire par ce fragment de code.

La réponse la plus constructive serait: Vous devez vous assurer qu'il n'y a que un seul IndexWriter écrit dans l'index à un moment donné et vous avez donc besoin d'un mécanisme pour vous en assurer. Donc, ma réponse dépend de ce que vous voulez accomplir:

  • voulez-vous une compréhension plus profonde de Lucene? ou..
  • voulez-vous juste construire et utiliser un index?

Si vous répondez est ce dernier, vous voudrez probablement regarder des projets comme Solr, qui cache toute la lecture et l'écriture de l'index.

 0
Author: M Platvoet, 2011-06-19 17:00:48

Cette question est probablement un duplicata de Trop de fichiers ouverts Erreur sur Lucene

Je répète ici ma réponse pour cela.

Utilisez l'index composé pour réduire le nombre de fichiers. Lorsque cet indicateur est défini, lucene écrira un segment en tant que single .fichier cfs au lieu de plusieurs fichiers. Cela réduira considérablement le nombre de fichiers.

IndexWriter.setUseCompoundFile(true)
 0
Author: Shashikant Kore, 2017-05-23 11:59:56