use of com.baidu.hugegraph.backend.query.ConditionQuery in project incubator-hugegraph by apache.
the class GraphIndexTransaction method doJointIndex.
@Watched(prefix = "index")
private IdHolder doJointIndex(IndexQueries queries) {
if (queries.oomRisk()) {
LOG.warn("There is OOM risk if the joint operation is based on a " + "large amount of data, please use single index + filter " + "instead of joint index: {}", queries.rootQuery());
}
// All queries are joined with AND
Set<Id> intersectIds = null;
boolean filtering = false;
IdHolder resultHolder = null;
for (Map.Entry<IndexLabel, ConditionQuery> e : queries.entrySet()) {
IndexLabel indexLabel = e.getKey();
ConditionQuery query = e.getValue();
assert !query.paging();
if (!query.noLimit() && queries.size() > 1) {
// Unset limit for intersection operation
query.limit(Query.NO_LIMIT);
}
/*
* Try to query by joint indexes:
* 1 If there is any index exceeded the threshold, transform into
* partial index query, then filter after back-table.
* 1.1 Return the holder of the first index that not exceeded the
* threshold if there exists one index, this holder will be used
* as the only query condition.
* 1.2 Return the holder of the first index if all indexes exceeded
* the threshold.
* 2 Else intersect holders for all indexes, and return intersection
* ids of all indexes.
*/
IdHolder holder = this.doIndexQuery(indexLabel, query);
if (resultHolder == null) {
resultHolder = holder;
this.storeSelectedIndexField(indexLabel, query);
}
// default value is 1000
assert this.indexIntersectThresh > 0;
Set<Id> ids = ((BatchIdHolder) holder).peekNext(this.indexIntersectThresh).ids();
if (ids.size() >= this.indexIntersectThresh) {
// Transform into filtering
filtering = true;
query.optimized(OptimizedType.INDEX_FILTER);
} else if (filtering) {
assert ids.size() < this.indexIntersectThresh;
resultHolder = holder;
this.storeSelectedIndexField(indexLabel, query);
break;
} else {
if (intersectIds == null) {
intersectIds = ids;
} else {
CollectionUtil.intersectWithModify(intersectIds, ids);
}
if (intersectIds.isEmpty()) {
break;
}
}
}
if (filtering) {
return resultHolder;
} else {
assert intersectIds != null;
return new FixedIdHolder(queries.asJointQuery(), intersectIds);
}
}
use of com.baidu.hugegraph.backend.query.ConditionQuery in project incubator-hugegraph by apache.
the class GraphIndexTransaction method constructSearchQuery.
private ConditionQuery constructSearchQuery(ConditionQuery query, MatchedIndex index) {
ConditionQuery newQuery = query;
Set<Id> indexFields = new HashSet<>();
// Convert has(key, text) to has(key, textContainsAny(word1, word2))
for (IndexLabel il : index.indexLabels()) {
if (il.indexType() != IndexType.SEARCH) {
continue;
}
Id indexField = il.indexField();
String fieldValue = (String) newQuery.userpropValue(indexField);
Set<String> words = this.segmentWords(fieldValue);
indexFields.add(indexField);
newQuery = newQuery.copy();
newQuery.unsetCondition(indexField);
newQuery.query(Condition.textContainsAny(indexField, words));
}
// Register results filter to compare property value and search text
newQuery.registerResultsFilter(element -> {
assert element != null;
for (Condition cond : query.conditions()) {
Object key = cond.isRelation() ? ((Relation) cond).key() : null;
if (key instanceof Id && indexFields.contains(key)) {
// This is an index field of search index
Id field = (Id) key;
HugeProperty<?> property = element.getProperty(field);
String propValue = propertyValueToString(property.value());
String fieldValue = (String) query.userpropValue(field);
if (this.matchSearchIndexWords(propValue, fieldValue)) {
continue;
}
return false;
}
if (!cond.test(element)) {
return false;
}
}
return true;
});
return newQuery;
}
use of com.baidu.hugegraph.backend.query.ConditionQuery in project incubator-hugegraph by apache.
the class GraphIndexTransaction method constructQueries.
private static IndexQueries constructQueries(ConditionQuery query, Set<IndexLabel> ils, Set<Id> propKeys) {
IndexQueries queries = IndexQueries.of(query);
for (IndexLabel il : ils) {
List<Id> fields = il.indexFields();
ConditionQuery newQuery = query.copy();
newQuery.resetUserpropConditions();
for (Id field : fields) {
if (!propKeys.contains(field)) {
break;
}
for (Condition c : query.userpropConditions(field)) {
newQuery.query(c);
}
}
ConditionQuery q = constructQuery(newQuery, il);
assert q != null;
queries.put(il, q);
}
return queries;
}
use of com.baidu.hugegraph.backend.query.ConditionQuery in project incubator-hugegraph by apache.
the class GraphIndexTransaction method doSingleOrCompositeIndex.
@Watched(prefix = "index")
private IdHolder doSingleOrCompositeIndex(IndexQueries queries) {
assert queries.size() == 1;
Map.Entry<IndexLabel, ConditionQuery> entry = queries.one();
IndexLabel indexLabel = entry.getKey();
ConditionQuery query = entry.getValue();
return this.doIndexQuery(indexLabel, query);
}
use of com.baidu.hugegraph.backend.query.ConditionQuery in project incubator-hugegraph by apache.
the class SchemaTransaction method getSchema.
/**
* Currently doesn't allow to exist schema with the same name
* @param type the query schema type
* @param name the query schema name
* @param <T> SubClass of SchemaElement
* @return the queried schema object
*/
protected <T extends SchemaElement> T getSchema(HugeType type, String name) {
LOG.debug("SchemaTransaction get {} by name '{}'", type.readableName(), name);
this.beforeRead();
ConditionQuery query = new ConditionQuery(type);
query.eq(HugeKeys.NAME, name);
QueryResults<BackendEntry> results = this.indexTx.query(query);
this.afterRead();
// Should not exist schema with same name
BackendEntry entry = results.one();
if (entry == null) {
return null;
}
return this.deserialize(entry, type);
}
Aggregations