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);
}
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;
}
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;
}
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;
}
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();
}
Aggregations