Search in sources :

Example 41 with ConditionQuery

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

the class SchemaIndexTransaction method queryByName.

@Watched(prefix = "index")
private QueryResults<BackendEntry> queryByName(ConditionQuery query) {
    if (!this.needIndexForName()) {
        return super.query(query);
    }
    IndexLabel il = IndexLabel.label(query.resultType());
    String name = (String) query.condition(HugeKeys.NAME);
    E.checkState(name != null, "The name in condition can't be null " + "when querying schema by name");
    ConditionQuery indexQuery;
    indexQuery = new ConditionQuery(HugeType.SECONDARY_INDEX, query);
    indexQuery.eq(HugeKeys.FIELD_VALUES, name);
    indexQuery.eq(HugeKeys.INDEX_LABEL_ID, il.id());
    IdQuery idQuery = new IdQuery(query.resultType(), query);
    Iterator<BackendEntry> entries = super.query(indexQuery).iterator();
    try {
        while (entries.hasNext()) {
            HugeIndex index = this.serializer.readIndex(graph(), indexQuery, entries.next());
            idQuery.query(index.elementIds());
            Query.checkForceCapacity(idQuery.idsSize());
        }
    } finally {
        CloseableIterator.closeIterator(entries);
    }
    if (idQuery.ids().isEmpty()) {
        return QueryResults.empty();
    }
    assert idQuery.idsSize() == 1 : idQuery.ids();
    if (idQuery.idsSize() > 1) {
        LOG.warn("Multiple ids are found with same name '{}': {}", name, idQuery.ids());
    }
    return super.query(idQuery);
}
Also used : BackendEntry(com.baidu.hugegraph.backend.store.BackendEntry) ConditionQuery(com.baidu.hugegraph.backend.query.ConditionQuery) IndexLabel(com.baidu.hugegraph.schema.IndexLabel) IdQuery(com.baidu.hugegraph.backend.query.IdQuery) HugeIndex(com.baidu.hugegraph.structure.HugeIndex) Watched(com.baidu.hugegraph.perf.PerfUtil.Watched)

Example 42 with ConditionQuery

use of com.baidu.hugegraph.backend.query.ConditionQuery 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 43 with ConditionQuery

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

the class GraphIndexTransaction method buildJointIndexesQueries.

private static IndexQueries buildJointIndexesQueries(ConditionQuery query, MatchedIndex index) {
    IndexQueries queries = IndexQueries.of(query);
    List<IndexLabel> allILs = new ArrayList<>(index.indexLabels());
    // Handle range/search indexes
    if (query.hasRangeCondition() || query.hasSearchCondition()) {
        Set<IndexLabel> matchedILs = matchRangeOrSearchIndexLabels(query, index.indexLabels());
        assert !matchedILs.isEmpty();
        allILs.removeAll(matchedILs);
        Set<Id> queryPropKeys = InsertionOrderUtil.newSet();
        for (IndexLabel il : matchedILs) {
            // Only one field each range/search index-label
            queryPropKeys.add(il.indexField());
        }
        // Construct queries by matched index-labels
        queries.putAll(constructQueries(query, matchedILs, queryPropKeys));
        // Remove matched queryPropKeys
        query = query.copy();
        for (Id field : queryPropKeys) {
            query.unsetCondition(field);
        }
        // Return if matched indexes satisfies query-conditions already
        if (query.userpropKeys().isEmpty()) {
            return queries;
        }
    }
    // Handle secondary joint indexes
    final ConditionQuery finalQuery = query;
    for (int i = 1, size = allILs.size(); i <= size; i++) {
        boolean found = cmn(allILs, size, i, 0, null, r -> {
            // All n indexLabels are selected, test current combination
            IndexQueries qs = constructJointSecondaryQueries(finalQuery, r);
            if (qs.isEmpty()) {
                return false;
            }
            queries.putAll(qs);
            return true;
        });
        if (found) {
            return queries;
        }
    }
    return IndexQueries.EMPTY;
}
Also used : ConditionQuery(com.baidu.hugegraph.backend.query.ConditionQuery) IndexLabel(com.baidu.hugegraph.schema.IndexLabel) ArrayList(java.util.ArrayList) Id(com.baidu.hugegraph.backend.id.Id)

Example 44 with ConditionQuery

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

the class GraphIndexTransaction method queryByLabel.

@Watched(prefix = "index")
private IdHolderList queryByLabel(ConditionQuery query) {
    HugeType queryType = query.resultType();
    IndexLabel il = IndexLabel.label(queryType);
    validateIndexLabel(il);
    Id label = query.condition(HugeKeys.LABEL);
    assert label != null;
    HugeType indexType;
    SchemaLabel schemaLabel;
    if (queryType.isVertex()) {
        indexType = HugeType.VERTEX_LABEL_INDEX;
        schemaLabel = this.graph().vertexLabel(label);
    } else if (queryType.isEdge()) {
        indexType = HugeType.EDGE_LABEL_INDEX;
        schemaLabel = this.graph().edgeLabel(label);
    } else {
        throw new HugeException("Can't query %s by label", queryType);
    }
    if (!this.store().features().supportsQueryByLabel() && !schemaLabel.enableLabelIndex()) {
        throw new NoIndexException("Don't accept query by label '%s', " + "label index is disabled", schemaLabel);
    }
    ConditionQuery indexQuery = new ConditionQuery(indexType, query);
    indexQuery.eq(HugeKeys.INDEX_LABEL_ID, il.id());
    indexQuery.eq(HugeKeys.FIELD_VALUES, label);
    /*
         * We can avoid redundant element ids if set limit, but if there are
         * label index overridden by other vertices with different label,
         * query with limit like g.V().hasLabel('xx').limit(10) may lose some
         * results, so can't set limit here. But in this case, the following
         * query results may be still different:
         *   g.V().hasLabel('xx').count()  // label index count
         *   g.V().hasLabel('xx').limit(-1).count()  // actual vertices count
         * It’s a similar situation for the offset, like:
         *   g.V().hasLabel('xx').range(26, 27)
         *   g.V().hasLabel('xx').range(27, 28)
         * we just reset limit here, but don't reset offset due to performance
         * optimization with index+offset query, see Query.skipOffsetIfNeeded().
         * NOTE: if set offset the backend itself will skip the offset
         */
    indexQuery.copyBasic(query);
    indexQuery.limit(Query.NO_LIMIT);
    IdHolder idHolder = this.doIndexQuery(il, indexQuery);
    IdHolderList holders = new IdHolderList(query.paging());
    holders.add(idHolder);
    return holders;
}
Also used : NoIndexException(com.baidu.hugegraph.exception.NoIndexException) SortByCountIdHolderList(com.baidu.hugegraph.backend.page.SortByCountIdHolderList) IdHolderList(com.baidu.hugegraph.backend.page.IdHolderList) ConditionQuery(com.baidu.hugegraph.backend.query.ConditionQuery) IndexLabel(com.baidu.hugegraph.schema.IndexLabel) IdHolder(com.baidu.hugegraph.backend.page.IdHolder) FixedIdHolder(com.baidu.hugegraph.backend.page.IdHolder.FixedIdHolder) PagingIdHolder(com.baidu.hugegraph.backend.page.IdHolder.PagingIdHolder) BatchIdHolder(com.baidu.hugegraph.backend.page.IdHolder.BatchIdHolder) SchemaLabel(com.baidu.hugegraph.schema.SchemaLabel) Id(com.baidu.hugegraph.backend.id.Id) HugeType(com.baidu.hugegraph.type.HugeType) HugeException(com.baidu.hugegraph.HugeException) Watched(com.baidu.hugegraph.perf.PerfUtil.Watched)

Example 45 with ConditionQuery

use of com.baidu.hugegraph.backend.query.ConditionQuery 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)

Aggregations

ConditionQuery (com.baidu.hugegraph.backend.query.ConditionQuery)59 Id (com.baidu.hugegraph.backend.id.Id)19 Test (org.junit.Test)19 Condition (com.baidu.hugegraph.backend.query.Condition)17 HugeGraph (com.baidu.hugegraph.HugeGraph)13 ArrayList (java.util.ArrayList)12 BaseUnitTest (com.baidu.hugegraph.unit.BaseUnitTest)10 Vertex (org.apache.tinkerpop.gremlin.structure.Vertex)10 Watched (com.baidu.hugegraph.perf.PerfUtil.Watched)8 Collection (java.util.Collection)8 Query (com.baidu.hugegraph.backend.query.Query)7 IndexLabel (com.baidu.hugegraph.schema.IndexLabel)7 PropertyKey (com.baidu.hugegraph.schema.PropertyKey)7 Map (java.util.Map)7 Edge (org.apache.tinkerpop.gremlin.structure.Edge)7 VertexLabel (com.baidu.hugegraph.schema.VertexLabel)6 IdQuery (com.baidu.hugegraph.backend.query.IdQuery)5 HugeEdge (com.baidu.hugegraph.structure.HugeEdge)5 HugeType (com.baidu.hugegraph.type.HugeType)5 ImmutableMap (com.google.common.collect.ImmutableMap)5