Search in sources :

Example 1 with LindenSortField

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);
}
Also used : LindenType(com.xiaomi.linden.thrift.common.LindenType) LindenSortField(com.xiaomi.linden.thrift.common.LindenSortField) LindenSortType(com.xiaomi.linden.thrift.common.LindenSortType)

Example 2 with LindenSortField

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;
}
Also used : LindenSortField(com.xiaomi.linden.thrift.common.LindenSortField)

Example 3 with LindenSortField

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;
}
Also used : ArrayList(java.util.ArrayList) LindenSortField(com.xiaomi.linden.thrift.common.LindenSortField) LindenResult(com.xiaomi.linden.thrift.common.LindenResult) LindenHit(com.xiaomi.linden.thrift.common.LindenHit) ArrayList(java.util.ArrayList) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList)

Example 4 with LindenSortField

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;
}
Also used : HashMap(java.util.HashMap) LindenSortField(com.xiaomi.linden.thrift.common.LindenSortField)

Example 5 with LindenSortField

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);
}
Also used : LindenSort(com.xiaomi.linden.thrift.common.LindenSort) ValueSource(org.apache.lucene.queries.function.ValueSource) Sort(org.apache.lucene.search.Sort) LindenSort(com.xiaomi.linden.thrift.common.LindenSort) SortField(org.apache.lucene.search.SortField) LindenSortField(com.xiaomi.linden.thrift.common.LindenSortField) Point(com.spatial4j.core.shape.Point) LindenSortField(com.xiaomi.linden.thrift.common.LindenSortField) Point(com.spatial4j.core.shape.Point)

Aggregations

LindenSortField (com.xiaomi.linden.thrift.common.LindenSortField)5 ImmutableList (com.google.common.collect.ImmutableList)1 Point (com.spatial4j.core.shape.Point)1 LindenHit (com.xiaomi.linden.thrift.common.LindenHit)1 LindenResult (com.xiaomi.linden.thrift.common.LindenResult)1 LindenSort (com.xiaomi.linden.thrift.common.LindenSort)1 LindenSortType (com.xiaomi.linden.thrift.common.LindenSortType)1 LindenType (com.xiaomi.linden.thrift.common.LindenType)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 List (java.util.List)1 ValueSource (org.apache.lucene.queries.function.ValueSource)1 Sort (org.apache.lucene.search.Sort)1 SortField (org.apache.lucene.search.SortField)1