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