Search in sources :

Example 1 with Order

use of com.google.apphosting.datastore.DatastoreV3Pb.Query.Order in project appengine-java-standard by GoogleCloudPlatform.

the class BaseEntityComparator method makeAdjustedOrders.

private static List<Order> makeAdjustedOrders(List<Order> orders, List<Filter> filters) {
    // Making arbitrary guess about order implied by exists filters.
    List<Order> existsOrders = Lists.newArrayList();
    for (Filter filter : filters) {
        if (filter.getOpEnum() == Filter.Operator.EXISTS) {
            existsOrders.add(new Order().setProperty(filter.getProperty(0).getName()).setDirection(Direction.ASCENDING));
        }
    }
    Collections.sort(existsOrders, ORDER_PROPERTY_COMPARATOR);
    List<Order> adjusted = new ArrayList<Order>(orders.size() + existsOrders.size() + 1);
    adjusted.addAll(orders);
    if (adjusted.isEmpty()) {
        // Check for a inequality filter to order by
        for (Filter filter : filters) {
            if (ValidatedQuery.INEQUALITY_OPERATORS.contains(filter.getOpEnum())) {
                // Only the first inequality is applied natively
                adjusted.add(new Order().setProperty(filter.getProperty(0).getName()).setDirection(Direction.ASCENDING));
                break;
            }
        }
    }
    adjusted.addAll(existsOrders);
    if (adjusted.isEmpty() || !adjusted.get(adjusted.size() - 1).equals(KEY_ASC_ORDER)) {
        // make sure we're always sorted by the key as the final sort order.
        adjusted.add(KEY_ASC_ORDER);
    }
    return adjusted;
}
Also used : Order(com.google.apphosting.datastore.DatastoreV3Pb.Query.Order) Filter(com.google.apphosting.datastore.DatastoreV3Pb.Query.Filter) ArrayList(java.util.ArrayList)

Example 2 with Order

use of com.google.apphosting.datastore.DatastoreV3Pb.Query.Order in project appengine-java-standard by GoogleCloudPlatform.

the class CompositeIndexManager method compositeIndexForQuery.

/**
 * Given a {@link IndexComponentsOnlyQuery}, return the {@link Index} needed to fulfill the query,
 * or {@code null} if no index is needed.
 *
 * <p>This code needs to remain in sync with its counterparts in other languages. If you modify
 * this code please make sure you make the same update in the local datastore for other languages.
 *
 * @param indexOnlyQuery The query.
 * @return The index that must be present in order to fulfill the query, or {@code null} if no
 *     index is needed.
 */
@Nullable
protected Index compositeIndexForQuery(final IndexComponentsOnlyQuery indexOnlyQuery) {
    DatastoreV3Pb.Query query = indexOnlyQuery.getQuery();
    boolean hasKind = query.hasKind();
    boolean isAncestor = query.hasAncestor();
    List<Filter> filters = query.filters();
    List<Order> orders = query.orders();
    if (filters.isEmpty() && orders.isEmpty()) {
        // built-in primary key or kind index can handle this.
        return null;
    }
    // Group the filters by operator.
    List<String> eqProps = indexOnlyQuery.getPrefix();
    List<Property> indexProperties = indexOnlyQuery.isGeo() ? getNeededSearchProps(eqProps, indexOnlyQuery.getGeoProperties()) : getRecommendedIndexProps(indexOnlyQuery);
    if (hasKind && !eqProps.isEmpty() && eqProps.size() == filters.size() && !indexOnlyQuery.hasKeyProperty() && orders.isEmpty()) {
        // specified, and those queries can _not_ be satisfied by merge-join.
        return null;
    }
    if (hasKind && !isAncestor && indexProperties.size() <= 1 && !indexOnlyQuery.isGeo() && (!indexOnlyQuery.hasKeyProperty() || indexProperties.get(0).getDirectionEnum() == Property.Direction.ASCENDING)) {
        // (a.k.a. Search) indexes, we might.)
        return null;
    }
    Index index = new Index();
    index.setEntityType(query.getKind());
    index.setAncestor(isAncestor);
    index.mutablePropertys().addAll(indexProperties);
    return index;
}
Also used : Order(com.google.apphosting.datastore.DatastoreV3Pb.Query.Order) Filter(com.google.apphosting.datastore.DatastoreV3Pb.Query.Filter) Index(com.google.storage.onestore.v3.OnestoreEntity.Index) DatastoreV3Pb(com.google.apphosting.datastore.DatastoreV3Pb) Property(com.google.storage.onestore.v3.OnestoreEntity.Index.Property) Nullable(org.checkerframework.checker.nullness.qual.Nullable)

Example 3 with Order

use of com.google.apphosting.datastore.DatastoreV3Pb.Query.Order in project appengine-java-standard by GoogleCloudPlatform.

the class IndexComponentsOnlyQuery method categorizeQuery.

private void categorizeQuery() {
    Set<String> ineqProps = Sets.newHashSet();
    hasKeyProperty = false;
    for (Filter filter : query.filters()) {
        String propName = filter.getProperty(0).getName();
        switch(filter.getOpEnum()) {
            case EQUAL:
                equalityProps.add(propName);
                break;
            case EXISTS:
                existsProps.add(propName);
                break;
            case GREATER_THAN:
            case GREATER_THAN_OR_EQUAL:
            case LESS_THAN:
            case LESS_THAN_OR_EQUAL:
                ineqProps.add(propName);
                break;
            case CONTAINED_IN_REGION:
                containmentProps.add(propName);
                break;
            default:
                throw new IllegalArgumentException("Unable to categorize query using filter operator " + filter.getOp());
        }
        if (propName.equals(Entity.KEY_RESERVED_PROPERTY)) {
            hasKeyProperty = true;
        }
    }
    // Add the inequality filter properties, if any.
    if (query.orderSize() == 0 && !ineqProps.isEmpty()) {
        // We do not add an index property for the inequality filter because
        // it will be taken care of when we add the sort on that same property
        // down below.
        orderProps.add(new Property().setName(ineqProps.iterator().next()));
    }
    groupByProps.addAll(query.groupByPropertyNames());
    // If a property is included in the group by, its existance will be satisfied.
    existsProps.removeAll(groupByProps);
    // Add orders.
    for (Order order : query.orders()) {
        if (order.getProperty().equals(Entity.KEY_RESERVED_PROPERTY)) {
            hasKeyProperty = true;
        }
        // If a property is in the ordering, it has already been satisfied.
        groupByProps.remove(order.getProperty());
        orderProps.add(new Property().setName(order.getProperty()).setDirection(order.getDirection()));
    }
}
Also used : Order(com.google.apphosting.datastore.DatastoreV3Pb.Query.Order) Filter(com.google.apphosting.datastore.DatastoreV3Pb.Query.Filter) Property(com.google.storage.onestore.v3.OnestoreEntity.Index.Property)

Example 4 with Order

use of com.google.apphosting.datastore.DatastoreV3Pb.Query.Order in project appengine-java-standard by GoogleCloudPlatform.

the class BaseEntityComparator method makeFilterMatchers.

private static Map<String, FilterMatcher> makeFilterMatchers(List<Order> orders, List<Filter> filters) {
    Map<String, FilterMatcher> filterMatchers = new HashMap<String, FilterMatcher>();
    for (Filter filter : filters) {
        String name = filter.getProperty(0).getName();
        FilterMatcher filterMatcher = filterMatchers.get(name);
        if (filterMatcher == null) {
            filterMatcher = new FilterMatcher();
            filterMatchers.put(name, filterMatcher);
        }
        filterMatcher.addFilter(filter);
    }
    // order implies existence filter
    for (Order order : orders) {
        if (!filterMatchers.containsKey(order.getProperty())) {
            filterMatchers.put(order.getProperty(), FilterMatcher.MATCH_ALL);
        }
        if (order.getProperty().equals(KEY_ASC_ORDER.getProperty())) {
            // sort orders after a key sort are ignored
            break;
        }
    }
    return filterMatchers;
}
Also used : Order(com.google.apphosting.datastore.DatastoreV3Pb.Query.Order) HashMap(java.util.HashMap) Filter(com.google.apphosting.datastore.DatastoreV3Pb.Query.Filter)

Example 5 with Order

use of com.google.apphosting.datastore.DatastoreV3Pb.Query.Order in project appengine-java-standard by GoogleCloudPlatform.

the class BaseEntityComparator method compare.

@Override
public int compare(EntityT entityA, EntityT entityB) {
    int result;
    // The first one that doesn't match determines our result
    for (Order order : orders) {
        String property = order.getProperty();
        Collection<Comparable<Object>> aValues = getComparablePropertyValues(entityA, property);
        Collection<Comparable<Object>> bValues = getComparablePropertyValues(entityB, property);
        // properties.
        if (aValues == null || bValues == null) {
            return 0;
        }
        // No guarantee that these collections all contain values of the same
        // type so we have to use our own method to find the extreme.  If we're
        // sorting in ascending order we want to compare the minimum values.
        // If we're sorting in descending order we want to compare the maximum
        // values.
        boolean findMin = order.getDirectionEnum() == DatastoreV3Pb.Query.Order.Direction.ASCENDING;
        FilterMatcher matcher = filters.get(property);
        if (matcher == null) {
            matcher = FilterMatcher.MATCH_ALL;
        }
        Comparable<Object> extremeA = multiTypeExtreme(aValues, findMin, matcher);
        Comparable<Object> extremeB = multiTypeExtreme(bValues, findMin, matcher);
        // No guarantee than extremeA and extremeB are of the same type so use
        // our multi-type aware comparison method.
        result = MULTI_TYPE_COMPARATOR.compare(extremeA, extremeB);
        if (result != 0) {
            if (order.getDirectionEnum() == DatastoreV3Pb.Query.Order.Direction.DESCENDING) {
                result = -result;
            }
            return result;
        }
    }
    // All sort properties match, so these are equal
    return 0;
}
Also used : Order(com.google.apphosting.datastore.DatastoreV3Pb.Query.Order)

Aggregations

Order (com.google.apphosting.datastore.DatastoreV3Pb.Query.Order)17 Filter (com.google.apphosting.datastore.DatastoreV3Pb.Query.Filter)10 EntityProtoComparator (com.google.appengine.api.datastore.EntityProtoComparators.EntityProtoComparator)5 Test (org.junit.Test)5 DatastoreV3Pb (com.google.apphosting.datastore.DatastoreV3Pb)3 Reference (com.google.storage.onestore.v3.OnestoreEntity.Reference)3 ByteString (com.google.protobuf.ByteString)2 OnestoreEntity (com.google.storage.onestore.v3.OnestoreEntity)2 EntityProto (com.google.storage.onestore.v3.OnestoreEntity.EntityProto)2 Index (com.google.storage.onestore.v3.OnestoreEntity.Index)2 Property (com.google.storage.onestore.v3.OnestoreEntity.Index.Property)2 Property (com.google.storage.onestore.v3.OnestoreEntity.Property)2 ArrayList (java.util.ArrayList)2 HashSet (java.util.HashSet)2 Key (com.google.appengine.api.datastore.Key)1 Utils.getLastElement (com.google.appengine.api.datastore.dev.Utils.getLastElement)1 CompiledQuery (com.google.apphosting.datastore.DatastoreV3Pb.CompiledQuery)1 GeoRegion (com.google.apphosting.datastore.DatastoreV3Pb.GeoRegion)1 Query (com.google.apphosting.datastore.DatastoreV3Pb.Query)1 Operator (com.google.apphosting.datastore.DatastoreV3Pb.Query.Filter.Operator)1