Hi,
Maybe this is an old thread or maybe it's different with previous one.
I want to custom solr sort and pass solr param from client to solr server,
so I implemented SearchComponent which named MySortComponent in my code,
and also implemented FieldComparatorSource and FieldComparator. when I use *
"mysearch" *requesthandler(see following codes),* I found that custom sort
just effect on the current page when I got multiple page results, but the
sort is expected when I sets the rows which contains all the
results.*Does anybody know how to solve it or the reason?
Thanks very much.
code snippet:
public class MySortComponent extends SearchComponent implements
SolrCoreAware {
public void inform(SolrCore arg0) {
}
@Override
public void prepare(ResponseBuilder rb) throws IOException {
SolrParams params = rb.req.getParams();
String uid = params.get("uid")
private RestTemplate restTemplate = new RestTemplate();
MyComparatorSource comparator = new MyComparatorSource(uid);
SortSpec sortSpec = rb.getSortSpec();
if (sortSpec.getSort() == null) {
sortSpec.setSort(new Sort(new SortField[] {
new SortField("relation",
comparator),SortField.FIELD_SCORE }));
} else {
SortField[] current = sortSpec.getSort().getSort();
ArrayList<SortField> sorts = new ArrayList<SortField>(
current.length + 1);
sorts.add(new SortField("relation", comparator));
for (SortField sf : current) {
sorts.add(sf);
}
sortSpec.setSort(new Sort(sorts.toArray(new
SortField[sorts.size()])));
}
}
@Override
public void process(ResponseBuilder rb) throws IOException {
}
//
---------------------------------------------------------------------------------
// SolrInfoMBean
//
---------------------------------------------------------------------------------
@Override
public String getDescription() {
return "Custom Sorting";
}
@Override
public String getSource() {
return "";
}
@Override
public URL[] getDocs() {
try {
return new URL[] { new URL(
"http://wiki.apache.org/solr/QueryComponent") };
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
public class MyComparatorSource extends FieldComparatorSource {
private BitSet dg1;
private BitSet dg2;
private BitSet dg3;
public MyComparatorSource(String uid) throws IOException {
SearchResponse responseBody = restTemplate.postForObject(
"http://search.test.com/userid/search/" + uid, null,
SearchResponse.class);
String d1 = responseBody.getOneDe();
String d2 = responseBody.getTwoDe();
String d3 = responseBody.getThreeDe();
if (StringUtils.hasLength(d1)) {
byte[] bytes = Base64.decodeBase64(d1);
dg1 = BitSetHelper.loadFromBzip2ByteArray(bytes);
}
if (StringUtils.hasLength(d2)) {
byte[] bytes = Base64.decodeBase64(d2);
dg2 = BitSetHelper.loadFromBzip2ByteArray(bytes);
}
if (StringUtils.hasLength(d3)) {
byte[] bytes = Base64.decodeBase64(d3);
dg3 = BitSetHelper.loadFromBzip2ByteArray(bytes);
}
}
@Override
public FieldComparator newComparator(String fieldname,
final int numHits, int sortPos, boolean reversed)
throws IOException {
return new RelationComparator(fieldname, numHits);
}
class RelationComparator extends FieldComparator {
private int[] uidDoc;
private float[] values;
private float bottom;
String fieldName;
public RelationComparator(String fieldName, int numHits)
throws IOException {
values = new float[numHits];
this.fieldName = fieldName;
}
@Override
public int compare(int slot1, int slot2) {
if (values[slot1] > values[slot2])
return -1;
if (values[slot1] < values[slot2])
return 1;
return 0;
}
@Override
public int compareBottom(int doc) throws IOException {
float docDistance = getRelation(doc);
if (bottom < docDistance)
return -1;
if (bottom > docDistance)
return 1;
return 0;
}
@Override
public void copy(int slot, int doc) throws IOException {
values[slot] = getRelation(doc);
}
@Override
public void setBottom(int slot) {
bottom = values[slot];
}
@Override
public FieldComparator<Integer> setNextReader(
AtomicReaderContext ctx) throws IOException {
uidDoc = FieldCache.DEFAULT.getInts(ctx.reader(), "userID",
true);
return this;
}
@Override
public Float value(int slot) {
return new Float(values[slot]);
}
private float getRelation(int doc) throws IOException {
if (dg3.get(uidDoc[doc])) {
return 3.0f;
} else if (dg2.get(uidDoc[doc])) {
return 4.0f;
} else if (dg1.get(uidDoc[doc])) {
return 5.0f;
} else {
return 1.0f;
}
}
@Override
public int compareDocToValue(int arg0, Object arg1)
throws IOException {
// TODO Auto-generated method stub
return 0;
}
}
}
}
and solrconfig.xml configuration is
<searchComponent name="mySortComponent"
class="com.tianji.solr.handler.component.MySortComponent"/>
<requestHandler name="/mysearch" class="solr.SearchHandler">
<arr name="last-components">
<str>mySortComponent</str>
</arr>
</requestHandler>
Andy