【问题标题】:What is the right way to get term positions in a Lucene document?在 Lucene 文档中获取术语位置的正确方法是什么?
【发布时间】:2018-11-22 21:16:36
【问题描述】:

The example in this question 和我在网上看到的其他一些使用TermVectorpostings 方法来获取术语位置。从链接问题的示例中复制粘贴:

IndexReader ir = obtainIndexReader();
Terms tv = ir.getTermVector( doc, field );
TermsEnum terms = tv.iterator();
PostingsEnum p = null;
while( terms.next() != null ) {
    p = terms.postings( p, PostingsEnum.ALL );
    while( p.nextDoc() != PostingsEnum.NO_MORE_DOCS ) {
        int freq = p.freq();
        for( int i = 0; i < freq; i++ ) {
            int pos = p.nextPosition();   // Always returns -1!!!
            BytesRef data = p.getPayload();
            doStuff( freq, pos, data ); // Fails miserably, of course.
        }
    }
}

这段代码对我有用,但让我抓狂的是Terms 类型是保存位置信息的地方。我看到的所有文档都在说术语向量保留位置数据。但是,此类型没有获取该信息的方法!

旧版本的 Lucene 显然有一个方法,但至少从 Lucene 6.5.1 版本开始,情况并非如此。

我应该使用postings 方法并遍历文档,但我已经知道要处理哪个文档!

API 文档没有说明只返回当前文档(术语向量所属的文档)的帖子,但是当我运行它时,我只得到当前文档。

这是从术语向量中获取位置数据的正确且唯一的方法吗?为什么会有这么不直观的 API?是否有文件解释了为什么以前的方法改为支持这一点?

【问题讨论】:

    标签: lucene


    【解决方案1】:

    不知道“对还是错”,但对于 6.6.3 版,这似乎可行。

    private void run() throws Exception {
        Directory directory = new RAMDirectory();
        IndexWriterConfig indexWriterConfig = new IndexWriterConfig(new StandardAnalyzer());
        IndexWriter writer = new IndexWriter(directory, indexWriterConfig);
    
        Document doc = new Document();
        // Field.Store.NO, Field.Index.ANALYZED, Field.TermVector.YES
        FieldType type = new FieldType();
        type.setStoreTermVectors(true);
        type.setStoreTermVectorPositions(true);
        type.setStoreTermVectorOffsets(true);
        type.setIndexOptions(IndexOptions.DOCS);
    
        Field fieldStore = new Field("tags", "foo bar and then some", type);
        doc.add(fieldStore);
        writer.addDocument(doc);
        writer.close();
    
        DirectoryReader reader = DirectoryReader.open(directory);
        IndexSearcher searcher = new IndexSearcher(reader);
    
        Term t = new Term("tags", "bar");
        Query q = new TermQuery(t);
        TopDocs results = searcher.search(q, 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);
                // for each term (iterator next) in this field (field)
                // iterate over the docs (should only be one)
                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("p="+ p + ", o=" + o + ", l=" + bytesRef.length + ", f=" + fr + ", s=" + bytesRef.utf8ToString());
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-06-18
      • 1970-01-01
      • 2012-02-14
      • 2018-04-29
      • 1970-01-01
      • 2011-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多