如何在Lucene中从文档术语向量中获取位置?

5

我需要遍历Lucene索引中的所有文档,并获取每个术语在每个文档中出现的位置。据我从Lucene javadoc中了解,实现这一点的方法是执行以下操作:

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.
        }
    }
}

然而,尽管(1)该索引确实包括相关字段上的位置,并且(2)术语向量声称具有位置(即:tv.hasPositions() == true),但我在所有位置上仍然得到“-1”。
首先,我是否做错了什么? 有没有其他按文档迭代过程中的帖子的替代方法? 其次:究竟发生了什么? 索引包含位置,由getTermVector返回的Terms实例声称包括位置,并且我在Luke中查看正确的位置值,但是当我尝试在代码中访问这些值时,我仍然得到-1。 怎么办?
编辑:相关字段使用以下选项配置:
    FieldType ft = new FieldType();
    ft.setIndexOptions( IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS );
    ft.setStoreTermVectors( true );
    ft.setStoreTermVectorOffsets( true );
    ft.setStoreTermVectorPayloads( true );
    ft.setStoreTermVectorPositions( true );
    ft.setTokenized( true );
    return ft;

事实证明,错误是由于缓存和重用PostingsEnum时的一些不相关错误引起的,因此jpountz的答案是正确的,我做错了。在这种情况下应该怎么办?删除这个问题吗? - jtatria
2个回答

4

的确如此,我会将FieldType配置添加到问题中。 - jtatria

0

我试过你的代码,它运行正常。
你是否正确地将FieldType添加到文档中?
我是这样做的:

Field ff = new Field("name", "value", ft);
document.add(ff);

谢谢您的回答,但是事实证明我犯了一个不相关的错误。请看我上面的评论。 - jtatria

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接