use of com.xiaomi.linden.thrift.common.LindenSortField in project linden by XiaoMi.
the class BQLCompilerAnalyzer method exitSort_spec.
@Override
public void exitSort_spec(BQLParser.Sort_specContext ctx) {
LindenSortField sortField;
if (ctx.DISTANCE() != null) {
sortField = new LindenSortField().setName("").setType(LindenSortType.DISTANCE);
} else if (ctx.SCORE() != null) {
sortField = new LindenSortField().setName("").setType(LindenSortType.SCORE);
} else {
String col = unescapeColumnName(ctx.column_name());
Map.Entry<String, LindenType> fieldNameAndType = getFieldNameAndType(col);
LindenType type = fieldNameAndType.getValue();
col = fieldNameAndType.getKey();
LindenSortType sortType = LindenSortType.findByValue(type.getValue());
sortField = new LindenSortField().setName(col).setType(sortType).setReverse(true);
}
if (ctx.ASC() != null) {
sortField.setReverse(false);
} else if (ctx.DESC() != null) {
sortField.setReverse(true);
}
valProperty.put(ctx, sortField);
}
use of com.xiaomi.linden.thrift.common.LindenSortField in project linden by XiaoMi.
the class LindenHitCmp method compare.
/**
* natural order is ascending:a negative integer, zero, or a positive integer
* as the first argument is less than, equal to, or greater than the second.
* if reverse natural order, the returned value * -1
* @param o1
* @param o2
* @return
*/
@Override
public int compare(LindenHit o1, LindenHit o2) {
int cmp = 0;
if (null == sortFields || sortFields.isEmpty()) {
cmp = Double.compare(o1.getScore(), o2.getScore());
return cmp * -1;
}
for (LindenSortField field : sortFields) {
int isReverse = field.isReverse() ? -1 : 1;
String v1 = o1.getFields().get(field.getName());
String v2 = o2.getFields().get(field.getName());
switch(field.getType()) {
case INTEGER:
cmp = Integer.compare(Integer.valueOf(v1), Integer.valueOf(v2));
break;
case LONG:
cmp = Long.compare(Long.valueOf(v1), Long.valueOf(v2));
break;
case FLOAT:
cmp = Float.compare(Float.valueOf(v1), Float.valueOf(v2));
break;
case DOUBLE:
cmp = Double.compare(Double.valueOf(v1), Double.valueOf(v2));
break;
case STRING:
cmp = v1.compareTo(v2);
break;
// but score is from high to low, distance is from near to far
case SCORE:
cmp = Double.compare(o1.getScore(), o2.getScore());
break;
case DISTANCE:
cmp = Double.compare(o1.getDistance(), o2.getDistance());
// distance is from near to far
cmp = cmp * -1;
break;
}
if (cmp != 0) {
return isReverse * cmp;
}
}
return 0;
}
use of com.xiaomi.linden.thrift.common.LindenSortField in project linden by XiaoMi.
the class ResultMerger method merge.
public static LindenResult merge(final LindenSearchRequest lindenRequest, final List<LindenResult> resultList) {
if (resultList == null || resultList.isEmpty()) {
return EMPTY_RESULT;
}
Iterator<LindenResult> iterator = resultList.iterator();
int failureCount = 0;
LindenResult failedResult = null;
while (iterator.hasNext()) {
LindenResult result = iterator.next();
if (!result.isSuccess()) {
failureCount++;
failedResult = result;
iterator.remove();
}
}
if (resultList.isEmpty()) {
if (failureCount == 1) {
LOGGER.error("The shard failed for search request {}", lindenRequest.toString());
return failedResult;
}
LOGGER.error("All shards failed for search request {}", lindenRequest.toString());
return ALL_SHARDS_FAILED_RESULT;
}
LindenResult mergedResult;
if (lindenRequest.isSetGroupParam()) {
// merge results for grouping search
mergedResult = mergeGroupSearch(lindenRequest, resultList);
} else {
// merge results for normal searching
mergedResult = new LindenResult().setTotalHits(0).setQueryInfo(resultList.get(0).queryInfo);
List<List<LindenHit>> hits = new ArrayList<>();
for (LindenResult result : resultList) {
mergedResult.totalHits += result.getTotalHits();
hits.add(result.getHits());
}
// merge LindenHit
List<LindenSortField> sortFields = lindenRequest.isSetSort() ? lindenRequest.getSort().getFields() : null;
Iterable<LindenHit> mergedHits = Iterables.mergeSorted(hits, new LindenHitCmp(sortFields));
List<LindenHit> topNHits = Lists.newArrayList(mergedHits);
if (lindenRequest.getOffset() <= topNHits.size()) {
List<LindenHit> subHits = topNHits.subList(lindenRequest.getOffset(), Math.min(lindenRequest.getOffset() + lindenRequest.getLength(), topNHits.size()));
mergedResult.setHits(subHits);
} else {
mergedResult.setHits(new ArrayList<LindenHit>());
}
}
// Merge facet result
if (lindenRequest.isSetFacet()) {
mergeFacet(lindenRequest, resultList, mergedResult);
}
if (failureCount > 0) {
mergedResult.setError(failureCount + " shards failed.");
}
return mergedResult;
}
use of com.xiaomi.linden.thrift.common.LindenSortField in project linden by XiaoMi.
the class LindenResultParser method parseSort.
private LindenHit parseSort(ScoreDoc hit, LindenHit lindenHit) {
if (request.isSetSort()) {
Map<String, String> fieldMap = new HashMap<>();
for (int i = 0; i < request.getSort().getFields().size(); ++i) {
LindenSortField field = request.getSort().getFields().get(i);
if (field.type == LindenSortType.SCORE || field.type == LindenSortType.DISTANCE) {
continue;
}
Object value = ((FieldDoc) hit).fields[i];
if (value == null) {
continue;
}
if (field.type == LindenSortType.STRING) {
fieldMap.put(field.getName(), ((BytesRef) value).utf8ToString());
} else {
fieldMap.put(field.getName(), value.toString());
}
}
lindenHit.setFields(fieldMap);
}
return lindenHit;
}
use of com.xiaomi.linden.thrift.common.LindenSortField in project linden by XiaoMi.
the class SortConstructor method constructSort.
public static Sort constructSort(LindenSearchRequest request, IndexSearcher indexSearcher, LindenConfig config) throws IOException {
if (!request.isSetSort())
return null;
LindenSort lindenSort = request.getSort();
SortField[] sortFields = new SortField[lindenSort.getFieldsSize()];
for (int i = 0; i < lindenSort.getFieldsSize(); ++i) {
LindenSortField field = lindenSort.getFields().get(i);
SortField.Type type = SortField.Type.STRING;
boolean isReverse = field.isReverse();
switch(field.getType()) {
case STRING:
type = SortField.Type.STRING;
break;
case DOUBLE:
type = SortField.Type.DOUBLE;
break;
case FLOAT:
type = SortField.Type.FLOAT;
break;
case INTEGER:
type = SortField.Type.INT;
break;
case LONG:
type = SortField.Type.LONG;
break;
case SCORE:
type = SortField.Type.SCORE;
isReverse = !isReverse;
break;
case DISTANCE:
if (request.isSetSpatialParam()) {
Point point = SpatialContext.GEO.makePoint(request.getSpatialParam().getCoordinate().getLongitude(), request.getSpatialParam().getCoordinate().getLatitude());
ValueSource valueSource = config.getSpatialStrategy().makeDistanceValueSource(point, DistanceUtils.DEG_TO_KM);
sortFields[i] = valueSource.getSortField(false).rewrite(indexSearcher);
}
continue;
}
sortFields[i] = new SortField(field.getName(), type, isReverse);
}
return new Sort(sortFields);
}
Aggregations