public boolean containsCondition(HugeKeys key) { return this.condition(key) != null; }
public static void verifyEdgesConditionQuery(ConditionQuery query) { assert query.resultType().isEdge(); int total = query.conditions().size(); if (total == 1) { // Supported: 1.query just by edge label, 2.query with scan if (query.containsCondition(HugeKeys.LABEL) || query.containsScanCondition()) { return; } } int matched = 0; for (HugeKeys key : EdgeId.KEYS) { Object value = query.condition(key); if (value == null) { break; } matched++; } if (matched != total) { throw new BackendException( "Not supported querying edges by %s, expect %s", query.conditions(), EdgeId.KEYS[matched]); } }
private Query writeQueryEdgePrefixCondition(ConditionQuery cq) { // Convert query-by-condition to query-by-id List<String> condParts = new ArrayList<>(cq.conditions().size()); for (HugeKeys key : EdgeId.KEYS) { Object value = cq.condition(key); if (value == null) { break; } // Serialize condition value if (key == HugeKeys.OWNER_VERTEX || key == HugeKeys.OTHER_VERTEX) { condParts.add(writeEntryId((Id) value)); } else if (key == HugeKeys.DIRECTION) { condParts.add(writeType(((Directions) value).type())); } else if (key == HugeKeys.LABEL) { condParts.add(writeId((Id) value)); } else { condParts.add(value.toString()); } } if (condParts.size() > 0) { // Conditions to id String id = EdgeId.concat(condParts.toArray(new String[0])); return new IdPrefixQuery(cq, IdGenerator.of(id)); } return null; }
protected static boolean isQueryByLabel(Query query) { Set<Condition> conditions = query.conditions(); if (query instanceof ConditionQuery && !conditions.isEmpty()) { ConditionQuery cq = (ConditionQuery) query; Id label = (Id) cq.condition(HugeKeys.LABEL); if (label != null && cq.allSysprop() && conditions.size() == 1 && cq.containsCondition(HugeKeys.LABEL, Condition.RelationType.EQ)) { return true; } } return false; }
private Query writeStringIndexQuery(ConditionQuery query) { E.checkArgument(query.allSysprop() && query.conditions().size() == 2, "There should be two conditions: " + "INDEX_LABEL_ID and FIELD_VALUES" + "in secondary index query"); Id index = (Id) query.condition(HugeKeys.INDEX_LABEL_ID); Object key = query.condition(HugeKeys.FIELD_VALUES); E.checkArgument(index != null, "Please specify the index label"); E.checkArgument(key != null, "Please specify the index key"); Id id = formatIndexId(query.resultType(), index, key); IdQuery idQuery = new IdQuery(query, id); idQuery.limit(query.limit()); idQuery.offset(query.offset()); return idQuery; }
public static boolean matchEdgeSortKeys(ConditionQuery query, HugeGraph graph) { assert query.resultType().isEdge(); Id label = (Id) query.condition(HugeKeys.LABEL); if (label == null) { return false; } List<Id> keys = graph.edgeLabel(label).sortKeys(); return !keys.isEmpty() && query.matchUserpropKeys(keys); }
/** * Mapping query-type to table-type * @param query origin query * @return corresponding table type */ public static HugeType tableType(Query query) { HugeType type = query.resultType(); // Mapping EDGE to EDGE_OUT/EDGE_IN if (type == HugeType.EDGE) { // We assume query OUT edges type = HugeType.EDGE_OUT; while (!(query instanceof ConditionQuery || query.originQuery() == null)) { /* * Some backends(like RocksDB) may trans ConditionQuery to * IdQuery or IdPrefixQuery, so we should get the origin query. */ query = query.originQuery(); } if (!query.conditions().isEmpty() && query instanceof ConditionQuery) { ConditionQuery cq = (ConditionQuery) query; // Does query IN edges if (cq.condition(HugeKeys.DIRECTION) == Directions.IN) { type = HugeType.EDGE_IN; } } } return type; }
BytesBuffer buffer = BytesBuffer.allocate(256); for (HugeKeys key : EdgeId.KEYS) { Object value = cq.condition(key);
public Query query(CassandraSessionPool.Session session, Query query) { Set<Condition> conditions = query.conditions(); if (!(query instanceof ConditionQuery) || conditions.isEmpty()) { return query; } ConditionQuery q = ((ConditionQuery) query).copy(); String name = (String) q.condition(HugeKeys.NAME); if (name != null && q.allSysprop() && conditions.size() == 1 && q.containsCondition(HugeKeys.NAME, Condition.RelationType.EQ)) { Set<Integer> ids = queryByNameIndex(session, this.table, name); if (ids.isEmpty()) { // Not found data with the specified label return null; } q.resetConditions(); for (Integer id : ids) { q.query(IdGenerator.of(id)); } } return q; }
/** * Query data from label index table if just want to query by label */ private static Query queryByLabelIndex( CassandraSessionPool.Session session, String table, Query query) { Set<Condition> conditions = query.conditions(); if (!(query instanceof ConditionQuery) || conditions.isEmpty()) { return query; } ConditionQuery q = (ConditionQuery) query; Id label = (Id) q.condition(HugeKeys.LABEL); if (label != null && q.allSysprop() && conditions.size() == 1 && q.containsCondition(HugeKeys.LABEL, Condition.RelationType.EQ)) { Set<String> ids = queryByLabelIndex(session, table, label); if (ids.isEmpty()) { // Not found data with the specified label return null; } q.resetConditions(); for (String id : ids) { /* * NOTE: Do not need to deserialize, because can directly * use the element id to do query from the vertex/edge table */ q.query(IdGenerator.of(id)); } } return query; }
@Watched(prefix = "index") private Set<Id> queryByUserprop(ConditionQuery query) { // Get user applied label or collect all qualified labels with // related index labels Set<MatchedIndex> indexes = this.collectMatchedIndexes(query); if (indexes.isEmpty()) { Id label = (Id) query.condition(HugeKeys.LABEL); throw noIndexException(this.graph(), query, label); } // Value type of Condition not matched if (!validQueryConditionValues(this.graph(), query)) { return ImmutableSet.of(); } // Do index query Set<Id> ids = InsertionOrderUtil.newSet(); for (MatchedIndex index : indexes) { if (index.containsSearchIndex()) { // Do search-index query ids.addAll(this.queryByUserpropWithSearchIndex(query, index)); } else { // Do secondary-index or range-index query IndexQueries queries = index.constructIndexQueries(query); ids.addAll(this.intersectIndexQueries(queries)); } if (query.reachLimit(ids.size())) { break; } } return limit(ids, query); }
@Watched(prefix = "index") private Set<MatchedIndex> collectMatchedIndexes(ConditionQuery query) { SchemaTransaction schema = this.graph().schemaTransaction(); Id label = (Id) query.condition(HugeKeys.LABEL);
@Override public HugeIndex readIndex(HugeGraph graph, ConditionQuery query, BackendEntry bytesEntry) { if (bytesEntry == null) { return null; } BinaryBackendEntry entry = this.convertEntry(bytesEntry); // NOTE: index id without length prefix byte[] bytes = entry.id().asBytes(1); HugeIndex index = HugeIndex.parseIndexId(graph, entry.type(), bytes); Object fieldValues = null; if (!index.type().isRangeIndex()) { fieldValues = query.condition(HugeKeys.FIELD_VALUES); if (!index.fieldValues().equals(fieldValues)) { // Update field-values for hashed index-id index.fieldValues(fieldValues); } } this.parseIndexName(entry, index, fieldValues); return index; }
@Watched(prefix = "index") private Iterator<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()); Iterator<BackendEntry> entries = super.query(indexQuery); IdQuery idQuery = new IdQuery(query.resultType(), query); while (entries.hasNext()) { HugeIndex index = this.serializer.readIndex(graph(), indexQuery, entries.next()); idQuery.query(index.elementIds()); } if (idQuery.ids().isEmpty()) { return Collections.emptyIterator(); } assert idQuery.ids().size() == 1 : idQuery.ids(); return super.query(idQuery); } }
private Query writeRangeIndexQuery(ConditionQuery query) { Id index = (Id) query.condition(HugeKeys.INDEX_LABEL_ID); E.checkArgument(index != null, "Please specify the index label");
@Watched(prefix = "index") private Set<Id> queryByLabel(ConditionQuery query) { HugeType queryType = query.resultType(); IndexLabel il = IndexLabel.label(queryType); Id label = (Id) query.condition(HugeKeys.LABEL); assert label != null; SchemaLabel schemaLabel; if (queryType.isVertex()) { schemaLabel = this.graph().vertexLabel(label); } else if (queryType.isEdge()) { schemaLabel = this.graph().edgeLabel(label); } else { throw new BackendException("Can't query %s by label", queryType); } if (!this.store().features().supportsQueryByLabel() && !schemaLabel.enableLabelIndex()) { throw new NoIndexException("Don't accept query by label '%s', " + "it disables label index", schemaLabel); } ConditionQuery indexQuery; indexQuery = new ConditionQuery(HugeType.SECONDARY_INDEX, query); indexQuery.eq(HugeKeys.INDEX_LABEL_ID, il.id()); indexQuery.eq(HugeKeys.FIELD_VALUES, label); // Set offset and limit to avoid redundant element ids indexQuery.limit(query.limit()); indexQuery.offset(query.offset()); indexQuery.capacity(query.capacity()); return this.doIndexQuery(il, indexQuery); }
public static boolean matchEdgeSortKeys(ConditionQuery query, HugeGraph graph) { assert query.resultType().isEdge(); Id label = (Id) query.condition(HugeKeys.LABEL); if (label == null) { return false; } List<Id> keys = graph.edgeLabel(label).sortKeys(); return !keys.isEmpty() && query.matchUserpropKeys(keys); }