lucene3.X实现自定义排序,主要是实现继承FieldComparatorSource抽象类的子类和继承FieldComparator的子类。
1.继承FieldComparatorSource,必须实现抽象方法newComparator。
2.继承FieldComparator,必须实现下面6个抽象方法:
compare(int, int) Compare a hit at 'slot a' with hit 'slot b'.
setBottom(int) This method is called by FieldValueHitQueue to notify the FieldComparator of the current weakest ("bottom") slot. Note that this slot may not hold the weakest value according to your comparator, in cases where your comparator is not the primary one (ie, is only used to break ties from the comparators before it).
compareBottom(int) Compare a new hit (docID) against the "weakest" (bottom) entry in the queue.
copy(int, int) Installs a new hit into the priority queue. The FieldValueHitQueue calls this method when a new hit is competitive.
setNextReader(org.apache.lucene.index.IndexReader, int) Invoked when the search is switching to the next segment. You may need to update internal state of the comparator, for example retrieving new values from the FieldCache.
value(int) Return the sort value stored in the specified slot. This is only called at the end of the search, in order to populate FieldDoc.fields when returning the top results.
上面方法描述摘自api文档,详细请查阅api。
例子是书上的一个简单例子,匹配结果根据用户所在地址(二维)查找离他最近的餐厅顺序排序。每个地点指定了三个域,即地名、二维坐标x和y,以及该地点的类型。下面是具体实现代码:
[java]
package org.apache.lucene.demo;
import java.io.IOException;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.FieldCache;
import org.apache.lucene.search.FieldComparator;
import org.apache.lucene.search.FieldComparatorSource;
import org.apache.lucene.search.SortField;
public class DistanceComparatorSource extends FieldComparatorSource{
private int x;
private int y;
public DistanceComparatorSource(int x,int y){
this.x = x;
this.y = y;
}
@Override
public FieldComparator< > newComparator(String arg0, int arg1, int arg2,
boolean arg3) throws IOException {
// TODO Auto-generated method stub
return new DistanceSourceLookupComparator(arg0, arg1);
}
private class DistanceSourceLookupComparator extends FieldComparator{
private int[] xDoc,yDoc;
private float[] values;
private float bottom;
String fieldName;
public DistanceSourceLookupComparator(String fieldName , int numHits){
values = new float[numHits];
this.fieldName = fieldName;
}
@Override
public int compare(int arg0, int arg1) {
// TODO Auto-generated method stub
if(values[arg0] > values[arg1]) return 1;
if(values[arg0] < values[arg1]) return -1;
return 0;
}
private float getDistance(int doc){
int deltax = xDoc[doc] - x ;
int deltay = yDoc[doc] - y;
return (float)Math.sqrt(deltax*deltax+deltay*deltay);
}
@Override
public int compareBottom(int arg0) throws IOException {
// TODO Auto-generated method stub
float distance = getDistance(arg0);
if(bottom < distance) return -1;
if(bottom > distance) return 1;
return 0