5
votes

I need to iterate over all documents in a Lucene index, and obtain the positions at which each term occurs in each document. As far as I am able to understand from the Lucene javadoc, the way to do this is to do something like this:

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

However, even though (1) the index does indeed include positions on the relevant field and (2) the term vector claims to have positions (i.e.: tv.hasPositions() == true), I keep getting "-1" for all positions.

First, am I doing something wrong? Is there an alternative way of iterating over postings on a per-document basis? Second: What is going on anyway? The index contains positions, the Terms instance returned by getTermVector claims to include positions, and I'm looking at the correct position values in Luke, yet I still get -1 when I try to access said values in my code. What gives?

EDIT: The relevant field was configured with the following options:

    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;
2
Turns out that the error was caused by some unrelated mistake with caching and reusing PostingsEnum, so jpountz's answer is correct, I was doing it wrong. What should one do in this case? delete the question?jtatria

2 Answers

3
votes
0
votes

Your code ran properly when i tried it.
Are you adding the FieldType properly to the document?
I did this:

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