Search in sources :

Example 31 with Condition

use of com.baidu.hugegraph.backend.query.Condition in project incubator-hugegraph by apache.

the class GraphTransaction method optimizeQuery.

private Query optimizeQuery(ConditionQuery query) {
    if (query.idsSize() > 0) {
        throw new HugeException("Not supported querying by id and conditions: %s", query);
    }
    Id label = (Id) query.condition(HugeKeys.LABEL);
    // Optimize vertex query
    if (label != null && query.resultType().isVertex()) {
        VertexLabel vertexLabel = this.graph().vertexLabel(label);
        if (vertexLabel.idStrategy() == IdStrategy.PRIMARY_KEY) {
            List<Id> keys = vertexLabel.primaryKeys();
            E.checkState(!keys.isEmpty(), "The primary keys can't be empty when using " + "'%s' id strategy for vertex label '%s'", IdStrategy.PRIMARY_KEY, vertexLabel.name());
            if (query.matchUserpropKeys(keys)) {
                // Query vertex by label + primary-values
                query.optimized(OptimizedType.PRIMARY_KEY);
                String primaryValues = query.userpropValuesString(keys);
                LOG.debug("Query vertices by primaryKeys: {}", query);
                // Convert {vertex-label + primary-key} to vertex-id
                Id id = SplicingIdGenerator.splicing(label.asString(), primaryValues);
                /*
                     * Just query by primary-key(id), ignore other userprop(if
                     * exists) that it will be filtered by queryVertices(Query)
                     */
                return new IdQuery(query, id);
            }
        }
    }
    // Optimize edge query
    if (query.resultType().isEdge() && label != null && query.condition(HugeKeys.OWNER_VERTEX) != null && query.condition(HugeKeys.DIRECTION) != null && matchEdgeSortKeys(query, false, this.graph())) {
        // Query edge by sourceVertex + direction + label + sort-values
        query.optimized(OptimizedType.SORT_KEYS);
        query = query.copy();
        // Serialize sort-values
        List<Id> keys = this.graph().edgeLabel(label).sortKeys();
        List<Condition> conditions = GraphIndexTransaction.constructShardConditions(query, keys, HugeKeys.SORT_VALUES);
        query.query(conditions);
        /*
             * Reset all userprop since transferred to sort-keys, ignore other
             * userprop(if exists) that it will be filtered by queryEdges(Query)
             */
        query.resetUserpropConditions();
        LOG.debug("Query edges by sortKeys: {}", query);
        return query;
    }
    /*
         * Query only by sysprops, like: by vertex label, by edge label.
         * NOTE: we assume sysprops would be indexed by backend store
         * but we don't support query edges only by direction/target-vertex.
         */
    if (query.allSysprop()) {
        if (query.resultType().isVertex()) {
            verifyVerticesConditionQuery(query);
        } else if (query.resultType().isEdge()) {
            verifyEdgesConditionQuery(query);
        }
        /*
             * Just support:
             *  1.not query by label
             *  2.or query by label and store supports this feature
             */
        boolean byLabel = (label != null && query.conditionsSize() == 1);
        if (!byLabel || this.store().features().supportsQueryByLabel()) {
            return query;
        }
    }
    return null;
}
Also used : Condition(com.baidu.hugegraph.backend.query.Condition) VertexLabel(com.baidu.hugegraph.schema.VertexLabel) IdQuery(com.baidu.hugegraph.backend.query.IdQuery) Id(com.baidu.hugegraph.backend.id.Id) EdgeId(com.baidu.hugegraph.backend.id.EdgeId) HugeException(com.baidu.hugegraph.HugeException)

Example 32 with Condition

use of com.baidu.hugegraph.backend.query.Condition in project incubator-hugegraph by apache.

the class GraphIndexTransaction method constructShardConditions.

protected static List<Condition> constructShardConditions(ConditionQuery query, List<Id> fields, HugeKeys key) {
    List<Condition> conditions = new ArrayList<>(2);
    boolean hasRange = false;
    int processedCondCount = 0;
    List<Object> prefixes = new ArrayList<>();
    for (Id field : fields) {
        List<Condition> fieldConds = query.userpropConditions(field);
        processedCondCount += fieldConds.size();
        if (fieldConds.isEmpty()) {
            break;
        }
        RangeConditions range = new RangeConditions(fieldConds);
        if (!range.hasRange()) {
            E.checkArgument(range.keyEq() != null, "Invalid query: %s", query);
            prefixes.add(range.keyEq());
            continue;
        }
        if (range.keyMin() != null) {
            RelationType type = range.keyMinEq() ? RelationType.GTE : RelationType.GT;
            conditions.add(shardFieldValuesCondition(key, prefixes, range.keyMin(), type));
        } else {
            assert range.keyMax() != null;
            Object num = range.keyMax();
            num = NumericUtil.minValueOf(NumericUtil.isNumber(num) ? num.getClass() : Long.class);
            conditions.add(shardFieldValuesCondition(key, prefixes, num, RelationType.GTE));
        }
        if (range.keyMax() != null) {
            RelationType type = range.keyMaxEq() ? RelationType.LTE : RelationType.LT;
            conditions.add(shardFieldValuesCondition(key, prefixes, range.keyMax(), type));
        } else {
            Object num = range.keyMin();
            num = NumericUtil.maxValueOf(NumericUtil.isNumber(num) ? num.getClass() : Long.class);
            conditions.add(shardFieldValuesCondition(key, prefixes, num, RelationType.LTE));
        }
        hasRange = true;
        break;
    }
    /*
         * Can't have conditions after range condition for shard index,
         * but SORT_KEYS can have redundant conditions because upper
         * layer can do filter.
         */
    if (key == HugeKeys.FIELD_VALUES && processedCondCount < query.userpropKeys().size()) {
        throw new HugeException("Invalid shard index query: %s", query);
    }
    // 1. First range condition processed, finish shard query conditions
    if (hasRange) {
        return conditions;
    }
    // 2. Shard query without range
    String joinedValues;
    // 2.1 All fields have equal-conditions
    if (prefixes.size() == fields.size()) {
        // Prefix numeric values should be converted to sortable string
        joinedValues = ConditionQuery.concatValues(prefixes);
        conditions.add(Condition.eq(key, joinedValues));
        return conditions;
    }
    // 2.2 Prefix fields have equal-conditions
    /*
         * Append EMPTY to 'values' to ensure FIELD_VALUES suffix
         * with IdGenerator.NAME_SPLITOR
         */
    prefixes.add(ConditionQuery.INDEX_VALUE_EMPTY);
    joinedValues = ConditionQuery.concatValues(prefixes);
    Condition min = Condition.gte(key, joinedValues);
    conditions.add(min);
    // Increase 1 on prefix to get the next prefix
    Condition max = Condition.lt(key, increaseString(joinedValues));
    conditions.add(max);
    return conditions;
}
Also used : Condition(com.baidu.hugegraph.backend.query.Condition) RelationType(com.baidu.hugegraph.backend.query.Condition.RelationType) ArrayList(java.util.ArrayList) Id(com.baidu.hugegraph.backend.id.Id) RangeConditions(com.baidu.hugegraph.backend.query.Condition.RangeConditions) HugeException(com.baidu.hugegraph.HugeException)

Example 33 with Condition

use of com.baidu.hugegraph.backend.query.Condition in project incubator-hugegraph by apache.

the class GraphIndexTransaction method constructQuery.

private static ConditionQuery constructQuery(ConditionQuery query, IndexLabel indexLabel) {
    IndexType indexType = indexLabel.indexType();
    boolean requireRange = query.hasRangeCondition();
    boolean supportRange = indexType.isNumeric();
    if (requireRange && !supportRange) {
        LOG.debug("There is range query condition in '{}', " + "but the index label '{}' is unable to match", query, indexLabel.name());
        return null;
    }
    Set<Id> queryKeys = query.userpropKeys();
    List<Id> indexFields = indexLabel.indexFields();
    if (!matchIndexFields(queryKeys, indexFields)) {
        return null;
    }
    LOG.debug("Matched index fields: {} of index '{}'", indexFields, indexLabel);
    ConditionQuery indexQuery;
    switch(indexType) {
        case SEARCH:
            E.checkState(indexFields.size() == 1, "Invalid index fields size for %s: %s", indexType, indexFields);
            Object fieldValue = query.userpropValue(indexFields.get(0));
            assert fieldValue instanceof String;
            // Will escape special char inside concatValues()
            fieldValue = ConditionQuery.concatValues(fieldValue);
            indexQuery = new ConditionQuery(indexType.type(), query);
            indexQuery.eq(HugeKeys.INDEX_LABEL_ID, indexLabel.id());
            indexQuery.eq(HugeKeys.FIELD_VALUES, fieldValue);
            break;
        case SECONDARY:
            List<Id> joinedKeys = indexFields.subList(0, queryKeys.size());
            // Will escape special char inside userpropValuesString()
            String joinedValues = query.userpropValuesString(joinedKeys);
            indexQuery = new ConditionQuery(indexType.type(), query);
            indexQuery.eq(HugeKeys.INDEX_LABEL_ID, indexLabel.id());
            indexQuery.eq(HugeKeys.FIELD_VALUES, joinedValues);
            break;
        case RANGE_INT:
        case RANGE_FLOAT:
        case RANGE_LONG:
        case RANGE_DOUBLE:
            if (query.userpropConditions().size() > 2) {
                throw new HugeException("Range query has two conditions at most, " + "but got: %s", query.userpropConditions());
            }
            // Replace the query key with PROPERTY_VALUES, set number value
            indexQuery = new ConditionQuery(indexType.type(), query);
            indexQuery.eq(HugeKeys.INDEX_LABEL_ID, indexLabel.id());
            for (Condition condition : query.userpropConditions()) {
                assert condition instanceof Condition.Relation;
                Condition.Relation r = (Condition.Relation) condition;
                Number value = NumericUtil.convertToNumber(r.value());
                Condition.Relation sys = new Condition.SyspropRelation(HugeKeys.FIELD_VALUES, r.relation(), value);
                condition = condition.replace(r, sys);
                indexQuery.query(condition);
            }
            break;
        case SHARD:
            HugeType type = indexLabel.indexType().type();
            indexQuery = new ConditionQuery(type, query);
            indexQuery.eq(HugeKeys.INDEX_LABEL_ID, indexLabel.id());
            List<Condition> conditions = constructShardConditions(query, indexLabel.indexFields(), HugeKeys.FIELD_VALUES);
            indexQuery.query(conditions);
            break;
        default:
            throw new AssertionError(String.format("Unknown index type '%s'", indexType));
    }
    /*
         * Set limit for single index or composite index, also for joint index,
         * to avoid redundant element ids and out of capacity.
         * NOTE: not set offset because this query might be a sub-query,
         * see queryByUserprop()
         */
    indexQuery.page(query.page());
    indexQuery.limit(query.total());
    indexQuery.capacity(query.capacity());
    indexQuery.olap(indexLabel.olap());
    return indexQuery;
}
Also used : Condition(com.baidu.hugegraph.backend.query.Condition) HugeException(com.baidu.hugegraph.HugeException) HugeType(com.baidu.hugegraph.type.HugeType) Relation(com.baidu.hugegraph.backend.query.Condition.Relation) Relation(com.baidu.hugegraph.backend.query.Condition.Relation) ConditionQuery(com.baidu.hugegraph.backend.query.ConditionQuery) Id(com.baidu.hugegraph.backend.id.Id) IndexType(com.baidu.hugegraph.type.define.IndexType)

Example 34 with Condition

use of com.baidu.hugegraph.backend.query.Condition in project incubator-hugegraph by apache.

the class RamTable method matched.

@Watched
public boolean matched(Query query) {
    if (this.edgesSize() == 0L || this.loading) {
        return false;
    }
    if (!query.resultType().isEdge() || !(query instanceof ConditionQuery)) {
        return false;
    }
    ConditionQuery cq = (ConditionQuery) query;
    int conditionsSize = cq.conditionsSize();
    Object owner = cq.condition(HugeKeys.OWNER_VERTEX);
    Directions direction = cq.condition(HugeKeys.DIRECTION);
    Id label = cq.condition(HugeKeys.LABEL);
    if (direction == null && conditionsSize > 1) {
        for (Condition cond : cq.conditions()) {
            if (cond.equals(BOTH_COND)) {
                direction = Directions.BOTH;
                break;
            }
        }
    }
    int matchedConds = 0;
    if (owner != null) {
        matchedConds++;
    } else {
        return false;
    }
    if (direction != null) {
        matchedConds++;
    }
    if (label != null) {
        matchedConds++;
    }
    return matchedConds == cq.conditionsSize();
}
Also used : Condition(com.baidu.hugegraph.backend.query.Condition) ConditionQuery(com.baidu.hugegraph.backend.query.ConditionQuery) Directions(com.baidu.hugegraph.type.define.Directions) Id(com.baidu.hugegraph.backend.id.Id) Watched(com.baidu.hugegraph.perf.PerfUtil.Watched)

Example 35 with Condition

use of com.baidu.hugegraph.backend.query.Condition in project incubator-hugegraph by apache.

the class ScyllaDBTablesWithMV method isQueryBySpecifiedKey.

private static boolean isQueryBySpecifiedKey(Query query, HugeKeys key) {
    Collection<Condition> conditions = query.conditions();
    if (query instanceof ConditionQuery && !conditions.isEmpty()) {
        ConditionQuery cq = (ConditionQuery) query;
        Object value = cq.condition(key);
        return value != null && cq.allSysprop() && conditions.size() == 1 && cq.containsRelation(key, Condition.RelationType.EQ);
    }
    return false;
}
Also used : Condition(com.baidu.hugegraph.backend.query.Condition) ConditionQuery(com.baidu.hugegraph.backend.query.ConditionQuery)

Aggregations

Condition (com.baidu.hugegraph.backend.query.Condition)49 BaseUnitTest (com.baidu.hugegraph.unit.BaseUnitTest)29 Test (org.junit.Test)29 ConditionQuery (com.baidu.hugegraph.backend.query.ConditionQuery)16 ArrayList (java.util.ArrayList)13 Id (com.baidu.hugegraph.backend.id.Id)12 Collection (java.util.Collection)8 Date (java.util.Date)8 SyspropRelation (com.baidu.hugegraph.backend.query.Condition.SyspropRelation)6 EdgeId (com.baidu.hugegraph.backend.id.EdgeId)4 RangeConditions (com.baidu.hugegraph.backend.query.Condition.RangeConditions)4 Relation (com.baidu.hugegraph.backend.query.Condition.Relation)4 HugeException (com.baidu.hugegraph.HugeException)3 IdPrefixQuery (com.baidu.hugegraph.backend.query.IdPrefixQuery)3 IdRangeQuery (com.baidu.hugegraph.backend.query.IdRangeQuery)3 HugeType (com.baidu.hugegraph.type.HugeType)3 Directions (com.baidu.hugegraph.type.define.Directions)3 HasContainer (org.apache.tinkerpop.gremlin.process.traversal.step.util.HasContainer)3 AndP (org.apache.tinkerpop.gremlin.process.traversal.util.AndP)3 OrP (org.apache.tinkerpop.gremlin.process.traversal.util.OrP)3