I'm changing one web application with lucene 2.4.1 to lucene 2.9.4 (basically because this bug: https://issues.apache.org/jira/browse/LUCENE-1304).
I'm trying to migrate a custom sort field according to some examples i read. But I cannot make it work right. I have a field with string values and when i find a pattern I extract a number (priority). This priority is used for sorting de documents. The field has values like this: "pub.generic1 pub.generic1.zonahome pub.generic1.zonahome.prio.1 pub.generic1.zonahome.lateral.slash.derecha pub.generic1.zonahome.lateral.slash.derecha.prio.1 pub.generic1.seccion.seccion1 pub.generic1.seccion.seccion1.prio.10" This is the new comparator code: public class HighTrafficSortComparator extends FieldComparatorSource { protected static final Log LOG = CmsLog.getLog(HighTrafficSortComparator.class); private List<String> priorityPreffix; private boolean ascending = false; public HighTrafficSortComparator(String[] prefifx, boolean ascending){ this.ascending = ascending; // here I make the preffix // ... } public FieldComparator newComparator(String fieldname, int numHits, int sortPos, boolean reversed) throws IOException { return new HighTrafficFieldComparator(numHits, fieldname); } class HighTrafficFieldComparator extends FieldComparator { String field; int[] docValues; int[] slotValues; int bottomValue; HighTrafficFieldComparator(int numHits, String fieldName) { slotValues = new int[numHits]; field = fieldName; } public void copy(int slot, int doc) { slotValues[slot] = docValues[doc]; } public int compare(int slot1, int slot2) { return slotValues[slot1] - slotValues[slot2]; } public int compareBottom(int doc) { return bottomValue - docValues[doc]; } public void setBottom(int bottom) { bottomValue = slotValues[bottom]; } public void setNextReader(IndexReader reader, int docBase) throws IOException { docValues = FieldCache.DEFAULT.getInts(reader, field, new FieldCache.IntParser() { public final int parseInt(final String val) { return getPrioridad(val); } }); } public Comparable value(int slot) { return new Integer(slotValues[slot]); } } private Integer getPrioridad(String text) { int prioridad = !ascending ? Integer.MAX_VALUE : Integer.MIN_VALUE; if (text!=null) { String[] termstext = text.split(" "); for (String termtext : termstext) { int idx = termtext.indexOf(NoticiacontentExtrator.KEY_SEPARATOR + "prio" + NoticiacontentExtrator.VALUE_SEPARATOR); if (idx>-1) { //is a priority. String termPreffix = termtext.substring(0,idx); if (priorityPreffix.contains(termPreffix)) { //has the requested priority try { int prioridadTerm = Integer.parseInt(termtext.substring(idx+6)); if (!ascending && prioridadTerm < prioridad) prioridad = prioridadTerm; else if (ascending && prioridadTerm > prioridad) prioridad = prioridadTerm; } catch (NumberFormatException ex) { } } } } } return new Integer(prioridad); } } this is how I use this custom sort: camposOrden = new SortField(luceneFieldName, new HighTrafficSortComparator(preffix,isAscending), isAscending); When I made the query the result is not sorted correclty... But I dont know what I doing wrong. This is the old code working correctly in lucene 2.4.1: public class HighTrafficSortComparator implements SortComparatorSource { private List<String> priorityPreffix; public ScoreDocComparator newComparator(final IndexReader indexReader, final String fieldname) throws IOException { return new ScoreDocComparator() { private Map<Integer,Integer> cachedScores = new HashMap<Integer,Integer>(); public int compare(ScoreDoc scoreDoc1, ScoreDoc scoreDoc2) { try { Integer priorityDoc1 = cachedScores.get(scoreDoc1.doc); Integer priorityDoc2 = cachedScores.get(scoreDoc2.doc); if (priorityDoc1==null) { final Document doc1 = indexReader.document(scoreDoc1.doc); final String strVal1 = doc1.get(fieldname); priorityDoc1 = getPrioridad(strVal1); cachedScores.put(scoreDoc1.doc, priorityDoc1); } if (priorityDoc2==null) { final Document doc2 = indexReader.document(scoreDoc2.doc); final String strVal2 = doc2.get(fieldname); priorityDoc2 = getPrioridad(strVal2); cachedScores.put(scoreDoc2.doc, priorityDoc2); } return priorityDoc1.compareTo(priorityDoc2); } catch (IOException e) { LOG.error("Cannot read doc", e); } return 0; } public Comparable sortValue(ScoreDoc scoreDoc) { try { Integer priorityDoc = cachedScores.get(scoreDoc.doc); if (priorityDoc==null) { final Document doc = indexReader.document(scoreDoc.doc); final String strVal = doc.get(fieldname); priorityDoc = getPrioridad(strVal); } return priorityDoc; } catch (IOException e) { LOG.error("Cannot read doc", e); } return 0; } public int sortType() { return SortField.CUSTOM; } private Integer getPrioridad(String text) { int prioridad = !ascending ? Integer.MAX_VALUE : Integer.MIN_VALUE; if (text!=null) { String[] termstext = text.split(" "); for (String termtext : termstext) { int idx = termtext.indexOf(NoticiacontentExtrator.KEY_SEPARATOR + "prio" + NoticiacontentExtrator.VALUE_SEPARATOR); if (idx>-1) { //Es una prioridad. String termPreffix = termtext.substring(0,idx); priorityPreffix.toString()); if (priorityPreffix.contains(termPreffix)) { //Tiene la prioridad solicitada. try { int prioridadTerm = Integer.parseInt(termtext.substring(idx+6)); if (!ascending && prioridadTerm < prioridad) prioridad = prioridadTerm; else if (ascending && prioridadTerm > prioridad) prioridad = prioridadTerm; } catch (NumberFormatException ex) { } } } } } return new Integer(prioridad); } }; } private boolean ascending = false; public HighTrafficSortComparator(String[] preffix, boolean ascending){ this.ascending = ascending; //made the preffix //... } } does anybody have a clue why this is not working? Thanks VĂctor Podberezski