2016-10-07 5 views
0

Ich verwende Lucene 's Funktionen, um eine einfache Möglichkeit, ähnliche Wörter innerhalb eines Textes zu vergleichen."TokenStream Vertragsverletzung: close() Aufruf fehlt" beim Aufruf von addDocument

Meine Idee ist, zu haben haben ein Analyzer auf meinem Fließtext ein TokenStream zu schaffen, und für jedes Token betreibe ich einen FuzzyQuery zu sehen, ob ich ein Spiel in meinem Index haben. Wenn nicht, indexiere ich einfach eine neue Document, die nur das neue eindeutige Wort enthält.

Hier ist, was ich bin immer tho:

Exception in thread "main" java.lang.IllegalStateException: TokenStream contract violation: close() call missing 
    at org.apache.lucene.analysis.Tokenizer.setReader(Tokenizer.java:90) 
    at org.apache.lucene.analysis.Analyzer$TokenStreamComponents.setReader(Analyzer.java:411) 
    at org.apache.lucene.analysis.standard.StandardAnalyzer$1.setReader(StandardAnalyzer.java:111) 
    at org.apache.lucene.analysis.Analyzer.tokenStream(Analyzer.java:165) 
    at org.apache.lucene.document.Field.tokenStream(Field.java:568) 
    at org.apache.lucene.index.DefaultIndexingChain$PerField.invert(DefaultIndexingChain.java:708) 
    at org.apache.lucene.index.DefaultIndexingChain.processField(DefaultIndexingChain.java:417) 
    at org.apache.lucene.index.DefaultIndexingChain.processDocument(DefaultIndexingChain.java:373) 
    at org.apache.lucene.index.DocumentsWriterPerThread.updateDocument(DocumentsWriterPerThread.java:231) 
    at org.apache.lucene.index.DocumentsWriter.updateDocument(DocumentsWriter.java:478) 
    at org.apache.lucene.index.IndexWriter.updateDocument(IndexWriter.java:1562) 
    at org.apache.lucene.index.IndexWriter.addDocument(IndexWriter.java:1307) 
    at org.myPackage.MyClass.addToIndex(MyClass.java:58) 

Relevante Code hier:

// Setup tokenStream based on StandardAnalyzer 
TokenStream tokenStream = analyzer.tokenStream(TEXT_FIELD_NAME, new StringReader(input)); 
tokenStream = new StopFilter(tokenStream, EnglishAnalyzer.getDefaultStopSet()); 
tokenStream = new ShingleFilter(tokenStream, 3); 
tokenStream.addAttribute(CharTermAttribute.class); 
tokenStream.reset(); 
... 
// Iterate and process each token from the stream 
while (tokenStream.incrementToken()) { 
    CharTermAttribute charTerm = tokenStream.getAttribute(CharTermAttribute.class); 
    processWord(charTerm.toString()); 
} 
... 
// Processing a word means looking for a similar one inside the index and, if not found, adding this one to the index 
void processWord(String word) { 
    ... 
    if (DirectoryReader.indexExists(index)) { 
     reader = DirectoryReader.open(index); 
     IndexSearcher searcher = new IndexSearcher(reader); 
     TopDocs searchResults = searcher.search(query, 1); 
     if (searchResults.totalHits > 0) { 
      Document foundDocument = searcher.doc(searchResults.scoreDocs[0].doc); 
      super.processWord(foundDocument.get(TEXT_FIELD_NAME)); 
     } else { 
      addToIndex(word); 
     } 
    } else { 
     addToIndex(word); 
    } 
    ... 
} 
... 
// Create a new Document to index the provided word 
void addWordToIndex(String word) throws IOException { 
    Document newDocument = new Document(); 
    newDocument.add(new TextField(TEXT_FIELD_NAME, new StringReader(word))); 
    indexWriter.addDocument(newDocument); 
    indexWriter.commit(); 
} 

Die Ausnahme zu sagen scheint, dass ich die TokenStream vor dem Hinzufügen Dinge auf den Index schließen sollte, aber dies macht keinen Sinn für mich, denn wie sind index und TokenStream verwandt? Ich meine, Index erhält nur eine Document, die eine String enthält, wobei die String, die von einer TokenStream kommt, irrelevant sein sollte.

Irgendein Tipp, wie man das löst?

Antwort

0

Das Problem liegt in der Wiederverwendung des gleichen Analysators, den der IndexWriter zu verwenden versucht. Sie haben einen TokenStream geöffnet, der von diesem Analyzer geöffnet wird, und Sie versuchen dann, ein Dokument zu indizieren. Dieses Dokument muss analysiert werden, aber das Analyseprogramm stellt fest, dass es noch alt ist. TokenStream ist noch offen und löst eine Ausnahme aus.

Um das Problem zu beheben, können Sie ein neues, separates Analysegerät zum Verarbeiten und Testen der Zeichenfolge erstellen, anstatt das zu verwenden, das IndexWriter verwendet.

+0

Oder ich kann nur mein Feld zu einem 'StringField' ändern, so dass es nicht analysiert wird. Ich habe nicht wirklich darüber nachgedacht, danke, dass du das Problem entdeckt hast! – StepTNT

+0

Das bedeutet, dass zwei Threads nicht gleichzeitig am selben Analysator arbeiten können, richtig? Also, Analysatoren sind nicht threadsicher? –

Verwandte Themen