Lucene на что можно заменить iterator в коде?

Идея такая:

  1. происходит поиск слова в тексте
  2. если слово было найден, то я хочу найти его позицию в тексте (а не в индексе)

мой код:

    
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 чтоб получить детали позиции

→ Ссылка