Search in sources :

Example 1 with Sorting

use of com.yahoo.search.query.Sorting in project vespa by vespa-engine.

the class UniqueGroupingSearcher method dedupe.

/**
 * Until we can use the grouping pagination features in 5.1, we'll have to support offset
 * by simply requesting and discarding hit #0 up to hit #offset.
 */
private static Result dedupe(Query query, Execution execution, String dedupField) {
    Sorting sorting = query.getRanking().getSorting();
    if (sorting != null && sorting.fieldOrders().size() > 1) {
        query.trace("Can not use grouping for deduping with multi-level sorting.", 3);
        // we'd ever want to actually use it (and a bit harder to implement as well).
        return execution.search(query);
    }
    int hits = query.getHits();
    int offset = query.getOffset();
    int groupingHits = hits + offset;
    GroupingRequest groupingRequest = GroupingRequest.newInstance(query);
    groupingRequest.setRootOperation(buildGroupingExpression(dedupField, groupingHits, query.getPresentation().getSummary(), sorting));
    query.setHits(0);
    query.setOffset(0);
    Result result = execution.search(query);
    // query could have changed further down in the chain
    query = result.getQuery();
    query.setHits(hits);
    query.setOffset(offset);
    Group root = groupingRequest.getResultGroup(result);
    if (null == root) {
        String msg = "Result group not found for deduping grouping request, returning empty result.";
        query.trace(msg, 3);
        log.log(LogLevel.WARNING, msg);
        throw new IllegalStateException("Failed to produce deduped result set.");
    }
    // hide our tracks
    result.hits().remove(root.getId().toString());
    GroupList resultGroups = root.getGroupList(dedupField);
    if (resultGroups == null) {
        query.trace("Deduping grouping request returned no hits, returning empty result.", 3);
        return result;
    }
    // Make sure that .addAll() doesn't re-order the hits we copy from the grouping
    // framework. The groups are already in the order they should be.
    result.hits().setOrderer(NOP_ORDERER);
    result.hits().addAll(getRequestedHits(resultGroups, offset, hits));
    Long countField = (Long) root.getField(LABEL_COUNT);
    long count = countField != null ? countField : 0;
    result.setTotalHitCount(count);
    return result;
}
Also used : Group(com.yahoo.search.grouping.result.Group) GroupList(com.yahoo.search.grouping.result.GroupList) Sorting(com.yahoo.search.query.Sorting) Result(com.yahoo.search.Result)

Example 2 with Sorting

use of com.yahoo.search.query.Sorting in project vespa by vespa-engine.

the class Organizer method assignOrderer.

private void assignOrderer(Section section, Resolution resolution, List<String> sourceList, HitGroup group) {
    if (section.getOrder() == null) {
        // then sort by relevance, source
        group.setOrderer(new HitSortOrderer(new RelevanceComparator(new SourceOrderComparator(sourceList))));
        return;
    }
    // replace a source field comparison by one which knows the source list order
    // and add default sorting at the end if necessary
    Sorting sorting = section.getOrder();
    int rankIndex = -1;
    int sourceIndex = -1;
    for (int i = 0; i < sorting.fieldOrders().size(); i++) {
        Sorting.FieldOrder order = sorting.fieldOrders().get(i);
        if ("[relevance]".equals(order.getFieldName()) || "[rank]".equals(order.getFieldName()))
            rankIndex = i;
        else if (order.getFieldName().equals("[source]"))
            sourceIndex = i;
    }
    ChainableComparator comparator;
    Sorting beforeSource = null;
    Sorting afterSource = null;
    if (sourceIndex >= 0) {
        // replace alphabetical sorting on source by sourceList order sorting
        if (// sort fields before the source
        sourceIndex > 0)
            beforeSource = new Sorting(new ArrayList<>(sorting.fieldOrders().subList(0, sourceIndex)));
        if (// sort fields after the source
        sorting.fieldOrders().size() > sourceIndex + 1)
            afterSource = new Sorting(new ArrayList<>(sorting.fieldOrders().subList(sourceIndex + 1, sorting.fieldOrders().size() + 1)));
        comparator = new SourceOrderComparator(sourceList, FieldComparator.create(afterSource));
        if (beforeSource != null)
            comparator = new FieldComparator(beforeSource, comparator);
    } else if (rankIndex >= 0) {
        // add sort by source at the end
        comparator = new FieldComparator(sorting, new SourceOrderComparator(sourceList));
    } else {
        // add sort by rank,source at the end
        comparator = new FieldComparator(sorting, new RelevanceComparator(new SourceOrderComparator(sourceList)));
    }
    group.setOrderer(new HitSortOrderer(comparator));
}
Also used : Sorting(com.yahoo.search.query.Sorting)

Example 3 with Sorting

use of com.yahoo.search.query.Sorting in project vespa by vespa-engine.

the class ValidateSortingSearcher method validate.

private ErrorMessage validate(Query query) {
    Sorting sorting = query.getRanking().getSorting();
    List<Sorting.FieldOrder> l = (sorting != null) ? sorting.fieldOrders() : null;
    if (l == null) {
        return null;
    }
    Map<String, AttributesConfig.Attribute> names = getAttributeNames();
    if (names == null) {
        return null;
    }
    String queryLocale = null;
    if (query.getModel().getLocale() != null) {
        queryLocale = query.getModel().getLocale().toString();
    }
    for (Sorting.FieldOrder f : l) {
        String name = f.getFieldName();
        if ("[rank]".equals(name) || "[docid]".equals(name)) {
        // built-in constants - ok
        } else if (names.containsKey(name)) {
            AttributesConfig.Attribute attrConfig = names.get(name);
            if (attrConfig != null) {
                if (f.getSortOrder() == Sorting.Order.UNDEFINED) {
                    f.setAscending(attrConfig.sortascending());
                }
                if (f.getSorter().getClass().equals(Sorting.AttributeSorter.class)) {
                    // This indicates that it shall use default.
                    if ((attrConfig.datatype() == AttributesConfig.Attribute.Datatype.STRING)) {
                        if (attrConfig.sortfunction() == AttributesConfig.Attribute.Sortfunction.UCA) {
                            String locale = attrConfig.sortlocale();
                            if (locale == null || locale.isEmpty()) {
                                locale = queryLocale;
                            }
                            // can only use UcaSorter if we have knowledge about wanted locale
                            if (locale != null) {
                                f.setSorter(new Sorting.UcaSorter(name, locale, Sorting.UcaSorter.Strength.UNDEFINED));
                            } else {
                                // wanted UCA but no locale known, so use lowercase as fallback
                                f.setSorter(new Sorting.LowerCaseSorter(name));
                            }
                        } else if (attrConfig.sortfunction() == AttributesConfig.Attribute.Sortfunction.LOWERCASE) {
                            f.setSorter(new Sorting.LowerCaseSorter(name));
                        } else if (attrConfig.sortfunction() == AttributesConfig.Attribute.Sortfunction.RAW) {
                            f.setSorter(new Sorting.RawSorter(name));
                        } else {
                            // default if no config found for this string attribute
                            f.setSorter(new Sorting.LowerCaseSorter(name));
                        }
                    }
                }
                if (f.getSorter() instanceof Sorting.UcaSorter) {
                    Sorting.UcaSorter sorter = (Sorting.UcaSorter) f.getSorter();
                    String locale = sorter.getLocale();
                    if (locale == null || locale.isEmpty()) {
                        // first fallback
                        locale = attrConfig.sortlocale();
                    }
                    if (locale == null || locale.isEmpty()) {
                        // second fallback
                        locale = queryLocale;
                    }
                    // final fallback
                    if (locale == null || locale.isEmpty()) {
                        locale = "en_US";
                    }
                    Sorting.UcaSorter.Strength strength = sorter.getStrength();
                    if (sorter.getStrength() == Sorting.UcaSorter.Strength.UNDEFINED) {
                        strength = config2Strength(attrConfig.sortstrength());
                    }
                    if ((sorter.getStrength() == Sorting.UcaSorter.Strength.UNDEFINED) || (sorter.getLocale() == null) || sorter.getLocale().isEmpty()) {
                        sorter.setLocale(locale, strength);
                    }
                }
            } else {
                return ErrorMessage.createInvalidQueryParameter("The cluster " + getClusterName() + " has attribute config for field: " + name);
            }
        } else {
            return ErrorMessage.createInvalidQueryParameter("The cluster " + getClusterName() + " has no sortable attribute named: " + name);
        }
    }
    return null;
}
Also used : Sorting(com.yahoo.search.query.Sorting)

Example 4 with Sorting

use of com.yahoo.search.query.Sorting in project vespa by vespa-engine.

the class SortingDegrader method setDegradation.

private void setDegradation(Query query) {
    query.trace("Using sorting degrading for performance - totalHits will be wrong. " + "Turn off with sorting.degrading=false.", 2);
    // ensured above
    Sorting.FieldOrder primarySort = query.getRanking().getSorting().fieldOrders().get(0);
    MatchPhase matchPhase = query.getRanking().getMatchPhase();
    matchPhase.setAttribute(primarySort.getFieldName());
    matchPhase.setAscending(primarySort.getSortOrder() == Sorting.Order.ASCENDING);
    if (matchPhase.getMaxHits() == null)
        matchPhase.setMaxHits(decideDefaultMaxHits(query));
}
Also used : MatchPhase(com.yahoo.search.query.ranking.MatchPhase) Sorting(com.yahoo.search.query.Sorting)

Example 5 with Sorting

use of com.yahoo.search.query.Sorting in project vespa by vespa-engine.

the class YqlParser method fetchSorting.

@NonNull
private OperatorNode<?> fetchSorting(OperatorNode<?> ast) {
    if (ast.getOperator() != SequenceOperator.SORT)
        return ast;
    List<FieldOrder> sortingInit = new ArrayList<>();
    List<OperatorNode<?>> sortArguments = ast.getArgument(1);
    for (OperatorNode<?> op : sortArguments) {
        OperatorNode<ExpressionOperator> fieldNode = op.<OperatorNode<ExpressionOperator>>getArgument(0);
        String field = fetchFieldRead(fieldNode);
        String locale = getAnnotation(fieldNode, SORTING_LOCALE, String.class, null, "locale used by sorting function");
        String function = getAnnotation(fieldNode, SORTING_FUNCTION, String.class, null, "sorting function for the specified attribute");
        String strength = getAnnotation(fieldNode, SORTING_STRENGTH, String.class, null, "strength for sorting function");
        AttributeSorter sorter;
        if (function == null) {
            sorter = new AttributeSorter(field);
        } else if (Sorting.LOWERCASE.equals(function)) {
            sorter = new LowerCaseSorter(field);
        } else if (Sorting.RAW.equals(function)) {
            sorter = new RawSorter(field);
        } else if (Sorting.UCA.equals(function)) {
            if (locale != null) {
                UcaSorter.Strength ucaStrength = UcaSorter.Strength.UNDEFINED;
                if (strength != null) {
                    if (Sorting.STRENGTH_PRIMARY.equalsIgnoreCase(strength)) {
                        ucaStrength = UcaSorter.Strength.PRIMARY;
                    } else if (Sorting.STRENGTH_SECONDARY.equalsIgnoreCase(strength)) {
                        ucaStrength = UcaSorter.Strength.SECONDARY;
                    } else if (Sorting.STRENGTH_TERTIARY.equalsIgnoreCase(strength)) {
                        ucaStrength = UcaSorter.Strength.TERTIARY;
                    } else if (Sorting.STRENGTH_QUATERNARY.equalsIgnoreCase(strength)) {
                        ucaStrength = UcaSorter.Strength.QUATERNARY;
                    } else if (Sorting.STRENGTH_IDENTICAL.equalsIgnoreCase(strength)) {
                        ucaStrength = UcaSorter.Strength.IDENTICAL;
                    } else {
                        throw newUnexpectedArgumentException(function, Sorting.STRENGTH_PRIMARY, Sorting.STRENGTH_SECONDARY, Sorting.STRENGTH_TERTIARY, Sorting.STRENGTH_QUATERNARY, Sorting.STRENGTH_IDENTICAL);
                    }
                    sorter = new UcaSorter(field, locale, ucaStrength);
                } else {
                    sorter = new UcaSorter(field, locale, ucaStrength);
                }
            } else {
                sorter = new UcaSorter(field);
            }
        } else {
            throw newUnexpectedArgumentException(function, "lowercase", "raw", "uca");
        }
        switch((SortOperator) op.getOperator()) {
            case ASC:
                sortingInit.add(new FieldOrder(sorter, Order.ASCENDING));
                break;
            case DESC:
                sortingInit.add(new FieldOrder(sorter, Order.DESCENDING));
                break;
            default:
                throw newUnexpectedArgumentException(op.getOperator(), SortOperator.ASC, SortOperator.DESC);
        }
    }
    sorting = new Sorting(sortingInit);
    return ast.getArgument(0);
}
Also used : UcaSorter(com.yahoo.search.query.Sorting.UcaSorter) RawSorter(com.yahoo.search.query.Sorting.RawSorter) FieldOrder(com.yahoo.search.query.Sorting.FieldOrder) LowerCaseSorter(com.yahoo.search.query.Sorting.LowerCaseSorter) ArrayList(java.util.ArrayList) Sorting(com.yahoo.search.query.Sorting) AttributeSorter(com.yahoo.search.query.Sorting.AttributeSorter) NonNull(edu.umd.cs.findbugs.annotations.NonNull)

Aggregations

Sorting (com.yahoo.search.query.Sorting)6 Result (com.yahoo.search.Result)1 Group (com.yahoo.search.grouping.result.Group)1 GroupList (com.yahoo.search.grouping.result.GroupList)1 AttributeSorter (com.yahoo.search.query.Sorting.AttributeSorter)1 FieldOrder (com.yahoo.search.query.Sorting.FieldOrder)1 LowerCaseSorter (com.yahoo.search.query.Sorting.LowerCaseSorter)1 RawSorter (com.yahoo.search.query.Sorting.RawSorter)1 UcaSorter (com.yahoo.search.query.Sorting.UcaSorter)1 MatchPhase (com.yahoo.search.query.ranking.MatchPhase)1 NonNull (edu.umd.cs.findbugs.annotations.NonNull)1 ArrayList (java.util.ArrayList)1 Test (org.junit.Test)1