Lucene на что можно заменить iterator в коде?
Идея такая:
- происходит поиск слова в тексте
- если слово было найден, то я хочу найти его позицию в тексте (а не в индексе)
мой код:
public void methodFromStack() throws Exception {
Directory directory = new RAMDirectory();
IndexWriterConfig indexWriterConfig = new IndexWriterConfig(new StandardAnalyzer());
IndexWriter writer = new IndexWriter(directory, indexWriterConfig);
Document doc = new Document();
FieldType type = new FieldType();
type.setStoreTermVectors(true);
type.setStoreTermVectorPositions(true);
type.setStoreTermVectorOffsets(true);
type.setStored(true);
type.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS);
Field fieldStore = new Field("tags", "Kite good world.", type);
doc.add(fieldStore);
writer.addDocument(doc);
writer.close();
DirectoryReader reader = DirectoryReader.open(directory);
IndexSearcher searcher = new IndexSearcher(reader);
//Поиск по словосочетанию с учетом отступа
QueryParser queryParser = new QueryParser("tags", new StandardAnalyzer());
Query query = queryParser.parse("\"Kite World\"~1");
TopDocs results = searcher.search(query, 1);
for ( ScoreDoc scoreDoc : results.scoreDocs) {
Fields termVs = reader.getTermVectors(scoreDoc.doc);
Terms f = termVs.terms("tags");
TermsEnum te = f.iterator();
PostingsEnum docsAndPosEnum = null;
BytesRef bytesRef;
while ((bytesRef = te.next()) != null) {
docsAndPosEnum = te.postings(docsAndPosEnum, PostingsEnum.ALL);
int nextDoc = docsAndPosEnum.nextDoc();
assert nextDoc != DocIdSetIterator.NO_MORE_DOCS;
final int fr = docsAndPosEnum.freq();
final int p = docsAndPosEnum.nextPosition();
final int o = docsAndPosEnum.startOffset();
System.out.println("Word: " + bytesRef.utf8ToString());
System.out.println("Position: "+ p + ", startOffset: " + o + " length: " + bytesRef.length + " Freg: " + fr);
if(fr > 1){
for(int iter = 1; iter <= fr-1; iter++) {
System.out.println("Possition: "+ docsAndPosEnum.nextPosition());
}
}
}
}
}
Я знаю, что после Lucene версии 3, при переходе на версию 4 были изменения в API и были убраны class TermFreqVector and class TermPositionVector, при этом я искал любые другие способы получить свое слово или term, но во всех случаях мне предлагали использовать итератор и проходить по всем terms из индекса.
Подскажите как можно заменить итератор? Можно ли вообще найти мой результатный term как-то не прибегая в проходу по всем элементам?
Ответы (1 шт):
Автор решения: Roman Konoval
→ Ссылка
Чтоб перейти сразу к нужному терму используйте seekExact:
TermsEnum te = f.iterator();
if (te.seekExact(new BytesRef(searchTerm))) {
// тут можно вызывать termsEnum.postings чтоб получить детали позиции