in hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/GraphTransaction.java [1384:1465]
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;
}