Index: src/java/org/apache/lucene/search/FuzzyQuery.java =================================================================== --- src/java/org/apache/lucene/search/FuzzyQuery.java (revision 889203) +++ src/java/org/apache/lucene/search/FuzzyQuery.java (working copy) @@ -23,6 +23,7 @@ import java.io.IOException; import java.util.PriorityQueue; +import java.util.Comparator; /** Implements the fuzzy search query. The similarity measurement * is based on the Levenshtein (edit distance) algorithm. @@ -133,39 +134,36 @@ } int maxSize = BooleanQuery.getMaxClauseCount(); - PriorityQueue stQueue = new PriorityQueue(1024); + // the additional comparator is a bad hack to not change the protected ScoreTerm compareTo order: + PriorityQueue stQueue = new PriorityQueue(11, new Comparator() { + // invert for backwards compatibility + public final int compare(final ScoreTerm a, final ScoreTerm b) { + return b.compareTo(a); + } + }); FilteredTermEnum enumerator = getEnum(reader); try { - ScoreTerm bottomSt = null; + ScoreTerm st = new ScoreTerm(); do { final Term t = enumerator.term(); if (t == null) break; - ScoreTerm st = new ScoreTerm(t, enumerator.difference()); - if (stQueue.size() < maxSize) { - // record the current bottom item - if (bottomSt == null || st.compareTo(bottomSt) > 0) { - bottomSt = st; - } - // add to PQ, as it is not yet filled up - stQueue.offer(st); - } else { - assert bottomSt != null; - // only add to PQ, if the ScoreTerm is greater than the current bottom, - // as all entries will be enqueued after the current bottom and will never be visible - if (st.compareTo(bottomSt) < 0) { - stQueue.offer(st); - } - } - //System.out.println("current: "+st.term+"("+st.score+"), bottom: "+bottomSt.term+"("+bottomSt.score+")"); + final float score = enumerator.difference(); + // ignore uncompetetive hits + if (stQueue.size() >= maxSize && score <= stQueue.peek().score) + continue; + // add new entry in PQ + st.term = t; + st.score = score; + stQueue.offer(st); + // possibly drop entries from queue + st = (stQueue.size() > maxSize) ? stQueue.poll() : new ScoreTerm(); } while (enumerator.next()); } finally { enumerator.close(); } BooleanQuery query = new BooleanQuery(true); - int size = Math.min(stQueue.size(), maxSize); - for(int i = 0; i < size; i++){ - ScoreTerm st = stQueue.poll(); + for (final ScoreTerm st : stQueue) { TermQuery tq = new TermQuery(st.term); // found a match tq.setBoost(getBoost() * st.score); // set the boost query.add(tq, BooleanClause.Occur.SHOULD); // add to query @@ -178,11 +176,14 @@ public Term term; public float score; + ScoreTerm() {} + public ScoreTerm(Term term, float score){ this.term = term; this.score = score; } + // this comparator has wrong direction, must be negated since Lucene 3.0.1 public int compareTo(ScoreTerm other) { if (this.score == other.score) return this.term.compareTo(other.term);