in hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/GraphIndexTransaction.java [1193:1287]
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 Relation;
Relation r = (Relation) condition;
Number value = NumericUtil.convertToNumber(r.value());
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;
}