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?
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
Das bedeutet, dass zwei Threads nicht gleichzeitig am selben Analysator arbeiten können, richtig? Also, Analysatoren sind nicht threadsicher? –