2
votes

I am upgrading to Solr 4.1 and having trouble retrieving position and offset information using the new API. My index comprises of one document with one field containing the string 'one quick brown fox jumped over one lazy dog'. I am querying my index for 'one' and trying to retrieve positions and offsets corresponding to 'one'.

Here is the code snippet

Terms terms=reader.getTermVector(docId, fieldName);
TermsEnum termsEnum= terms.iterator(TermsEnum.EMPTY);
    BytesRef term;
    while((term=termsEnum.next())!=null){
        String docTerm = term.utf8ToString();
        DocsAndPositionsEnum docPosEnum = termsEnum.docsAndPositions(null, null, DocsAndPositionsEnum.FLAG_OFFSETS);
        //Check if the current term is the same as the query term and if so
        //retrieve all positions (can be multiple occurrences of a term in a field) corresponding to the term
        if (queryTerms.contains(docTerm)) {
            int position;
            while((position=docPosEnum.nextPosition())!=-1){
                int start=docPosEnum.startOffset();
                int end=docPosEnum.endOffset();
                //Store start, end and position in an a list
                }
        }
    }

The inner while loop is incorrect. Any pointers on how to iterate through all positions in a DocsAndPositionsEnum will be greatly appreciated.

2

2 Answers

8
votes

Here is what worked for me

Terms terms=reader.getTermVector(docId, fieldName);
TermsEnum termsEnum= terms.iterator(TermsEnum.EMPTY);
BytesRef term;
while((term=termsEnum.next())!=null){
            String docTerm = term.utf8ToString();
            //Check if the current term is the same as the query term and if so
            //retrieve all positions (can be multiple occurrences of a term in a field) corresponding to the term
            if (queryTerms.contains(docTerm)) {
                DocsAndPositionsEnum docPosEnum = termsEnum.docsAndPositions(null, null, DocsAndPositionsEnum.FLAG_OFFSETS);
                docPosEnum.nextDoc();
                //Retrieve the term frequency in the current document
                int freq=docPosEnum.freq();
                for(int i=0; i<freq; i++){
                    int position=docPosEnum.nextPosition();
                    int start=docPosEnum.startOffset();
                    int end=docPosEnum.endOffset();
                    //Store start, end and position in a list
                    }
            }
    }
1
votes

You aren't iterating to a Document in your DocsAndPositionsEnum.

    if (queryTerms.contains(docTerm)) {
        docPosEnum.advance(docId)
        int freq=docPosEnum.freq();
        for(int i=0; i<freq; i++){
            int position=docPosEnum.nextPosition();
            int end=docPosEnum.endOffset();
            //Store start, end and position in an a list
        }
    }

You'll likely want to store the docid returned from docPosEnum.nextDoc(), I would guess.