如何获取 lucene 索引中每个术语的帖子列表

Posted

技术标签:

【中文标题】如何获取 lucene 索引中每个术语的帖子列表【英文标题】:How to get the postings list for each term in lucene index 【发布时间】:2019-03-17 22:22:34 【问题描述】:

我正在阅读 lucene 索引,并且能够从索引中检索术语。我想获取 lucene 索引中每个术语的所有帖子列表。我正在使用 lucene 7.4.0 jar。该索引中的每个文档都包含两个字段(1)text_es 或 text_fr 或 text_en(2)DocId。下面是代码。

public class LuceneTest 

public static void main(String[] args) 
    final String INDEX_DIRECTORY = "./index";
    Directory index;
        try 

            index = FSDirectory.open(Paths.get(INDEX_DIRECTORY));
            IndexReader indexReader = DirectoryReader.open(index);

            LeafReaderContext leafReaderContext_es = indexReader.leaves().get(0);
            LeafReaderContext leafReaderContext_fr = indexReader.leaves().get(1);
            LeafReaderContext leafReaderContext_en = indexReader.leaves().get(2);

            LinkedList<String> terms_es = new LinkedList<>();
            LinkedList<String> terms_en = new LinkedList<>();
            LinkedList<String> terms_fr = new LinkedList<>();

            LeafReader ir_es = leafReaderContext_es.reader();
            LeafReader ir_fr = leafReaderContext_fr.reader();
            LeafReader ir_en = leafReaderContext_en.reader();

            TermsEnum terms = ir_es.terms("text_es").iterator();
            BytesRef next = terms.next();
            while (next != null)
                terms_es.add(terms.term().utf8ToString());
                next = terms.next();
            

            TermsEnum termsEnum_fr = ir_fr.terms("text_fr").iterator();
            BytesRef next_fr = termsEnum_fr.next();
            while (next_fr != null)
                terms_fr.add(termsEnum_fr.term().utf8ToString());
                next_fr = termsEnum_fr.next();
            

            TermsEnum termsEnum_en = ir_en.terms("text_en").iterator();
            BytesRef next_en = termsEnum_en.next();
            while (next_en != null)
                terms_en.add(termsEnum_en.term().utf8ToString());
                next_en = termsEnum_en.next();
            

            System.out.println("Espanish terms are as follows:");
            System.out.println(terms_es);

            System.out.println("French terms are as follows:");
            System.out.println(terms_fr);

            System.out.println("English terms are as follows:");
            System.out.println(terms_en);


         catch (IOException e) 
            e.printStackTrace();
        

我浏览了 lucene 7.4.0 的文档并遇到了方法 posts(Term term),它返回 PostingsEnum 和 PostingsEnum.FREQS 的指定术语。问题是这个方法接受类 Term 的参数项,但我得到的是 TermsEnum。如何将其转换为 Term 类,以便我可以使用方法 postsings 来检索每个术语的相应发布列表。

谢谢。

【问题讨论】:

【参考方案1】:

我用的是lucene 8.2,你可以试试下面的代码:

    IndexReader indexReader = DirectoryReader.open(indexDir);
    Terms termVector = indexReader.getTermVector(0, "content");
    TermsEnum termIter = termVector.iterator();
    while (termIter.next() != null) 
        PostingsEnum postingsEnum = termIter.postings(null, PostingsEnum.ALL);
        while (postingsEnum.nextDoc() != DocIdSetIterator.NO_MORE_DOCS) 
            int freq = postingsEnum.freq();
            System.out.printf("term: %s, freq: %d,", termIter.term().utf8ToString(), freq);
            while (freq > 0) 
                System.out.printf(" nextPosition: %d,", postingsEnum.nextPosition());
                System.out.printf(" startOffset: %d, endOffset: %d",
                        postingsEnum.startOffset(), postingsEnum.endOffset());
                freq--;
            
            System.out.println();
        
    

【讨论】:

以上是关于如何获取 lucene 索引中每个术语的帖子列表的主要内容,如果未能解决你的问题,请参考以下文章

如何获取和使用每个列表成员的索引

Lucene的算法

如何使用Term或QueryParser从Lucene索引中删除文档

如何优化这个非常慢的 MySQL 查询?

如何在solr中获取lucene索引的版本

无法获取术语或调用函数