static <T, U> GraphTraversal<T, U> assignVar(GraphTraversal<T, U> traversal, Var var, Collection<Var> vars) { if (!vars.contains(var)) { // This variable name has not been encountered before, remember it and use the 'as' step return traversal.as(var.name()); } else { // This variable name has been encountered before, confirm it is the same return traversal.where(P.eq(var.name())); } }
/** * @param vars set of variables of interest * @param tx the graph to get results from * @param elements a map of vertices and edges where the key is the variable name * @return a map of concepts where the key is the variable name */ private static Map<Var, Concept> makeResults( Set<Var> vars, EmbeddedGraknTx<?> tx, Map<String, Element> elements) { Map<Var, Concept> map = new HashMap<>(); for (Var var : vars) { Element element = elements.get(var.name()); if (element == null) { throw GraqlQueryException.unexpectedResult(var); } else { Concept concept = buildConcept(tx, element); map.put(var, concept); } } return map; }
private static <S, E> GraphTraversal<S, Map<String, E>> selectVars(GraphTraversal<S, ?> traversal, Set<Var> vars) { if (vars.isEmpty()) { // Produce an empty result return traversal.constant(ImmutableMap.of()); } else if (vars.size() == 1) { String label = vars.iterator().next().name(); return traversal.select(label, label); } else { String[] labelArray = vars.stream().map(Var::name).toArray(String[]::new); return traversal.asAdmin().addStep(new SelectStep<>(traversal.asAdmin(), null, labelArray)); } }
private GraphTraversal<Vertex, Edge> edgeRelationTraversal( EmbeddedGraknTx<?> tx, Direction direction, Schema.EdgeProperty roleProperty, Collection<Var> vars) { GraphTraversal<Vertex, Edge> edgeTraversal = __.toE(direction, Schema.EdgeLabel.ATTRIBUTE.getLabel()); // Identify the relation - role-player pair by combining the relationship edge and direction into a map edgeTraversal.as(RELATION_EDGE.name()).constant(direction).as(RELATION_DIRECTION.name()); edgeTraversal.select(Pop.last, RELATION_EDGE.name(), RELATION_DIRECTION.name()).as(edge().name()).select(RELATION_EDGE.name()); // Filter by any provided type labels applyLabelsToTraversal(edgeTraversal, roleProperty, roleLabels(), tx); applyLabelsToTraversal(edgeTraversal, RELATIONSHIP_TYPE_LABEL_ID, relationTypeLabels(), tx); traverseToRole(edgeTraversal, role(), roleProperty, vars); return edgeTraversal; }
private GraphTraversal<Element, Vertex> edgeRelationTraversal( EmbeddedGraknTx<?> tx, Direction direction, Schema.EdgeProperty roleProperty, Collection<Var> vars) { GraphTraversal<Element, Edge> edgeTraversal = Fragments.isEdge(__.identity()); // Filter by any provided type labels applyLabelsToTraversal(edgeTraversal, roleProperty, roleLabels(), tx); applyLabelsToTraversal(edgeTraversal, RELATIONSHIP_TYPE_LABEL_ID, relationTypeLabels(), tx); traverseToRole(edgeTraversal, role(), roleProperty, vars); // Identify the relation - role-player pair by combining the relationship edge and direction into a map edgeTraversal.as(RELATION_EDGE.name()).constant(direction).as(RELATION_DIRECTION.name()); edgeTraversal.select(Pop.last, RELATION_EDGE.name(), RELATION_DIRECTION.name()).as(edge().name()).select(RELATION_EDGE.name()); return edgeTraversal.toV(direction); }
@Override public GraphTraversal<Vertex, ? extends Element> applyTraversalInner( GraphTraversal<Vertex, ? extends Element> traversal, EmbeddedGraknTx<?> graph, Collection<Var> vars) { return traversal.where(P.neq(other().name())); }
/** * Optionally traverse from a {@link Schema.EdgeLabel#ROLE_PLAYER} edge to the {@link Role} it mentions, plus any super-types. * * @param traversal the traversal, starting from the {@link Schema.EdgeLabel#ROLE_PLAYER} edge * @param role the variable to assign to the role. If not present, do nothing * @param edgeProperty the edge property to look up the role label ID */ static void traverseToRole( GraphTraversal<?, Edge> traversal, @Nullable Var role, Schema.EdgeProperty edgeProperty, Collection<Var> vars) { if (role != null) { Var edge = Graql.var(); traversal.as(edge.name()); Fragments.outSubs(Fragments.traverseSchemaConceptFromEdge(traversal, edgeProperty)); assignVar(traversal, role, vars).select(edge.name()); } } }
@Override public final <S, E> GraphTraversal<S, E> applyPredicate(GraphTraversal<S, E> traversal) { var.ifPresent(theVar -> { // Compare to another variable String thisVar = UUID.randomUUID().toString(); Var otherVar = theVar.var(); String otherValue = UUID.randomUUID().toString(); Traversal[] traversals = Stream.of(VALUE_PROPERTIES) .map(prop -> __.values(prop).as(otherValue).select(thisVar).values(prop).where(gremlinPredicate(otherValue))) .toArray(Traversal[]::new); traversal.as(thisVar).select(otherVar.name()).or(traversals).select(thisVar); }); persistedValue().ifPresent(theValue -> { // Compare to a given value DataType<?> dataType = DataType.SUPPORTED_TYPES.get(value().get().getClass().getTypeName()); Schema.VertexProperty property = dataType.getVertexProperty(); traversal.has(property.name(), gremlinPredicate(theValue)); }); return traversal; }
static <S> GraphTraversal<S, Vertex> traverseSchemaConceptFromEdge( GraphTraversal<S, Edge> traversal, Schema.EdgeProperty edgeProperty) { // Access label ID from edge Var labelId = Graql.var(); traversal.values(edgeProperty.name()).as(labelId.name()); // Look up schema concept using ID return traversal.V().has(LABEL_ID.name(), __.where(P.eq(labelId.name()))); }
/** * @param traversal the traversal to extend with this Fragment * @param tx the graph to execute the traversal on */ public final GraphTraversal<Vertex, ? extends Element> applyTraversal( GraphTraversal<Vertex, ? extends Element> traversal, EmbeddedGraknTx<?> tx, Collection<Var> vars, @Nullable Var currentVar) { if (currentVar != null) { if (!currentVar.equals(start())) { if (vars.contains(start())) { // If the variable name has been visited but the traversal is not at that variable name, select it traversal.select(start().name()); } else { // Restart traversal when fragments are disconnected traversal.V().as(start().name()); } } } else { // If the variable name has not been visited yet, remember it and use the 'as' step traversal.as(start().name()); } vars.add(start()); traversal = applyTraversalInner(traversal, tx, vars); Var end = end(); if (end != null) { assignVar(traversal, end, vars); } vars.addAll(vars()); return traversal; }
private GraphTraversal<Vertex, Edge> toEdgeInstances() { Var type = var(); Var labelId = var(); // There is no fast way to retrieve all edge instances, because edges cannot be globally indexed. // This is a best-effort, that uses the schema to limit the search space... // First retrieve the type ID GraphTraversal<Vertex, Vertex> traversal = __.<Vertex>as(type.name()).values(LABEL_ID.name()).as(labelId.name()).select(type.name()); // Next, navigate the schema to all possible types whose instances can be in this relation traversal = Fragments.inSubs(traversal.out(RELATES.getLabel()).in(PLAYS.getLabel())); // Navigate to all (vertex) instances of those types // (we do not need to navigate to edge instances, because edge instances cannot be role-players) traversal = toVertexInstances(traversal); // Finally, navigate to all relation edges with the correct type attached to these instances return traversal.outE(ATTRIBUTE.getLabel()) .has(RELATIONSHIP_TYPE_LABEL_ID.name(), __.where(P.eq(labelId.name()))); }
private GraphTraversal<Vertex, Vertex> reifiedRelationTraversal(EmbeddedGraknTx<?> tx, Collection<Var> vars) { GraphTraversal<Vertex, Edge> edgeTraversal = __.<Vertex>inE(ROLE_PLAYER.getLabel()).as(edge().name()); // Filter by any provided type labels applyLabelsToTraversal(edgeTraversal, ROLE_LABEL_ID, roleLabels(), tx); applyLabelsToTraversal(edgeTraversal, RELATIONSHIP_TYPE_LABEL_ID, relationTypeLabels(), tx); traverseToRole(edgeTraversal, role(), ROLE_LABEL_ID, vars); return edgeTraversal.outV(); }
private GraphTraversal<Element, Vertex> reifiedRelationTraversal(EmbeddedGraknTx<?> tx, Collection<Var> vars) { GraphTraversal<Element, Vertex> traversal = Fragments.isVertex(__.identity()); GraphTraversal<Element, Edge> edgeTraversal = traversal.outE(ROLE_PLAYER.getLabel()).as(edge().name()); // Filter by any provided type labels applyLabelsToTraversal(edgeTraversal, ROLE_LABEL_ID, roleLabels(), tx); applyLabelsToTraversal(edgeTraversal, RELATIONSHIP_TYPE_LABEL_ID, relationTypeLabels(), tx); traverseToRole(edgeTraversal, role(), ROLE_LABEL_ID, vars); return edgeTraversal.inV(); }