You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-user@lucene.apache.org by Victor Podberezski <vp...@cms-medios.com> on 2015/01/13 02:59:49 UTC

Problem with Custom FieldComparator

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