Index: src/java/org/apache/lucene/search/ExactPhraseScorer.java =================================================================== --- src/java/org/apache/lucene/search/ExactPhraseScorer.java (revision 447480) +++ src/java/org/apache/lucene/search/ExactPhraseScorer.java (working copy) @@ -28,6 +28,7 @@ protected final float phraseFreq() throws IOException { // sort list with pq + pq.clear(); for (PhrasePositions pp = first; pp != null; pp = pp.next) { pp.firstPosition(); pq.put(pp); // build pq from list Index: src/java/org/apache/lucene/search/PhraseQueue.java =================================================================== --- src/java/org/apache/lucene/search/PhraseQueue.java (revision 447480) +++ src/java/org/apache/lucene/search/PhraseQueue.java (working copy) @@ -27,7 +27,10 @@ PhrasePositions pp1 = (PhrasePositions)o1; PhrasePositions pp2 = (PhrasePositions)o2; if (pp1.doc == pp2.doc) - return pp1.position < pp2.position; + if (pp1.position == pp2.position) + return pp1.position+pp1.offset < pp2.position+pp2.offset; + else + return pp1.position < pp2.position; else return pp1.doc < pp2.doc; } Index: src/java/org/apache/lucene/search/PhraseScorer.java =================================================================== --- src/java/org/apache/lucene/search/PhraseScorer.java (revision 447480) +++ src/java/org/apache/lucene/search/PhraseScorer.java (working copy) @@ -93,6 +93,7 @@ } public boolean skipTo(int target) throws IOException { + firstTime = false; for (PhrasePositions pp = first; more && pp != null; pp = pp.next) { more = pp.skipTo(target); } Index: src/test/org/apache/lucene/search/QueryUtils.java =================================================================== --- src/test/org/apache/lucene/search/QueryUtils.java (revision 467721) +++ src/test/org/apache/lucene/search/QueryUtils.java (working copy) @@ -97,11 +97,15 @@ s.search(q,new HitCollector() { public void collect(int doc, float score) { try { - boolean more = (which[0]++&0x02)==0 ? scorer.skipTo(sdoc[0]+1) : scorer.next(); + boolean more = (which[0]++&0x02)==0 ? scorer.skipTo(sdoc[0]+1) : scorer.next(); //skip skip next next skip skip +// boolean more = (which[0]++&0x02)!=0 ? scorer.skipTo(sdoc[0]+1) : scorer.next(); //next next skip skip next next +// boolean more = (which[0]++&0x01)==0 ? scorer.skipTo(sdoc[0]+1) : scorer.next(); //skip next skip next skip next +// boolean more = (which[0]++&0x01)!=0 ? scorer.skipTo(sdoc[0]+1) : scorer.next(); //next skip next skip next skip +// boolean more = (which[0]++&0x01)==7 ? scorer.skipTo(sdoc[0]+1) : scorer.next(); //only next() +// boolean more = (which[0]++&0x01)!=7 ? scorer.skipTo(sdoc[0]+1) : scorer.next(); //only skipTo() sdoc[0] = scorer.doc(); float scorerScore = scorer.score(); float scoreDiff = Math.abs(score-scorerScore); - scoreDiff=0; // TODO: remove this go get LUCENE-697 failures if (more==false || doc != sdoc[0] || scoreDiff>maxDiff) { throw new RuntimeException("ERROR matching docs:" +"\n\tscorer.more=" + more + " doc="+sdoc[0] + " score="+scorerScore