__.inE(Schema.EdgeLabel.ROLE_PLAYER.getLabel()). as("edge"). has(ROLE_LABEL_ID.name(), P.within(ownerToValueOrdering? ownerRoleIds : valueRoleIds)). outV(). outE(Schema.EdgeLabel.ROLE_PLAYER.getLabel()). has(ROLE_LABEL_ID.name(), P.within(ownerToValueOrdering? valueRoleIds : ownerRoleIds)). where(P.neq("edge")). inV() __.inE(Schema.EdgeLabel.ROLE_PLAYER.getLabel()). as("edge"). outV(). outE(Schema.EdgeLabel.ROLE_PLAYER.getLabel()). where(P.neq("edge")). inV(); GraphTraversal<Vertex, Vertex> attributeEdgeTraversal = __.outE(Schema.EdgeLabel.ATTRIBUTE.getLabel()).inV();
public <X extends Concept> X buildConcept(EdgeElement edgeElement){ Schema.EdgeLabel label = Schema.EdgeLabel.valueOf(edgeElement.label().toUpperCase(Locale.getDefault())); ConceptId conceptId = ConceptId.of(edgeElement.id().getValue()); if(!tx.txCache().isConceptCached(conceptId)){ Concept concept; switch (label) { case ATTRIBUTE: concept = RelationshipImpl.create(RelationshipEdge.get(edgeElement)); break; default: throw GraknTxOperationException.unknownConcept(label.name()); } tx.txCache().cacheConcept(concept); } return tx.txCache().getCachedConcept(conceptId); }
/** * If the edge does not exist then it adds a {@link Schema.EdgeLabel#ROLE_PLAYER} edge from * this {@link Relationship} to a target {@link Thing} which is playing some {@link Role}. * * If the edge does exist nothing is done. * * @param role The {@link Role} being played by the {@link Thing} in this {@link Relationship} * @param toThing The {@link Thing} playing a {@link Role} in this {@link Relationship} */ public void putRolePlayerEdge(Role role, Thing toThing) { //Checking if the edge exists GraphTraversal<Vertex, Edge> traversal = vertex().tx().getTinkerTraversal().V(). has(Schema.VertexProperty.ID.name(), this.id().getValue()). outE(Schema.EdgeLabel.ROLE_PLAYER.getLabel()). has(Schema.EdgeProperty.RELATIONSHIP_TYPE_LABEL_ID.name(), this.type().labelId().getValue()). has(Schema.EdgeProperty.ROLE_LABEL_ID.name(), role.labelId().getValue()). as("edge"). inV(). has(Schema.VertexProperty.ID.name(), toThing.id()). select("edge"); if(traversal.hasNext()){ return; } //Role player edge does not exist create a new one EdgeElement edge = this.addEdge(ConceptVertex.from(toThing), Schema.EdgeLabel.ROLE_PLAYER); edge.property(Schema.EdgeProperty.RELATIONSHIP_TYPE_LABEL_ID, this.type().labelId().getValue()); edge.property(Schema.EdgeProperty.ROLE_LABEL_ID, role.labelId().getValue()); Casting casting = Casting.create(edge, owner, role, toThing); vertex().tx().txCache().trackForValidation(casting); }
Iterator<Edge> edges = element().edges(direction, label.getLabel()); if(targets.length == 0){ edges.forEachRemaining(Edge::remove);
/** * Castings are retrieved from the perspective of the {@link Relationship} * * @param roles The {@link Role} which the {@link Thing}s are playing * @return The {@link Casting} which unify a {@link Role} and {@link Thing} with this {@link Relationship} */ public Stream<Casting> castingsRelation(Role... roles){ Set<Role> roleSet = new HashSet<>(Arrays.asList(roles)); if(roleSet.isEmpty()){ return vertex().getEdgesOfType(Direction.OUT, Schema.EdgeLabel.ROLE_PLAYER). map(edge -> Casting.withRelationship(edge, owner)); } //Traversal is used so we can potentially optimise on the index Set<Integer> roleTypesIds = roleSet.stream().map(r -> r.labelId().getValue()).collect(Collectors.toSet()); return vertex().tx().getTinkerTraversal().V(). has(Schema.VertexProperty.ID.name(), id().getValue()). outE(Schema.EdgeLabel.ROLE_PLAYER.getLabel()). has(Schema.EdgeProperty.RELATIONSHIP_TYPE_LABEL_ID.name(), type().labelId().getValue()). has(Schema.EdgeProperty.ROLE_LABEL_ID.name(), P.within(roleTypesIds)). toStream(). map(edge -> vertex().tx().factory().buildEdgeElement(edge)). map(edge -> Casting.withRelationship(edge, owner)); }
private void applyFilters(Set<LabelId> types, boolean includesRolePlayerEdge) { if (types == null || types.isEmpty()) return; Set<Integer> labelIds = types.stream().map(LabelId::getValue).collect(Collectors.toSet()); Traversal<Vertex, Vertex> vertexFilter = __.has(Schema.VertexProperty.THING_TYPE_LABEL_ID.name(), P.within(labelIds)); Traversal<Vertex, Edge> edgeFilter; if (filterAllEdges) { edgeFilter = __.<Vertex>bothE().limit(0); } else { edgeFilter = includesRolePlayerEdge ? __.union( __.<Vertex>bothE(Schema.EdgeLabel.ROLE_PLAYER.getLabel()), __.<Vertex>bothE(Schema.EdgeLabel.ATTRIBUTE.getLabel()) .has(Schema.EdgeProperty.RELATIONSHIP_TYPE_LABEL_ID.name(), P.within(labelIds))) : __.<Vertex>bothE(Schema.EdgeLabel.ATTRIBUTE.getLabel()) .has(Schema.EdgeProperty.RELATIONSHIP_TYPE_LABEL_ID.name(), P.within(labelIds)); } graphComputer.vertices(vertexFilter).edges(edgeFilter); } }
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 Stream<Relationship> relationEdges(){ //Unfortunately this is a slow process return roles(). flatMap(Role::players). flatMap(type ->{ //Traversal is used here to take advantage of vertex centric index return vertex().tx().getTinkerTraversal().V(). has(Schema.VertexProperty.ID.name(), type.id().getValue()). in(Schema.EdgeLabel.SHARD.getLabel()). in(Schema.EdgeLabel.ISA.getLabel()). outE(Schema.EdgeLabel.ATTRIBUTE.getLabel()). has(Schema.EdgeProperty.RELATIONSHIP_TYPE_LABEL_ID.name(), labelId().getValue()). toStream(). map(edge -> vertex().tx().factory().<Relationship>buildConcept(edge)); }); }
/** * @param to the target {@link VertexElement} * @param type the type of the edge to create */ public EdgeElement putEdge(VertexElement to, Schema.EdgeLabel type){ GraphTraversal<Vertex, Edge> traversal = tx().getTinkerTraversal().V(). has(Schema.VertexProperty.ID.name(), id().getValue()). outE(type.getLabel()).as("edge").otherV(). has(Schema.VertexProperty.ID.name(), to.id().getValue()).select("edge"); if(!traversal.hasNext()) { return addEdge(to, type); } else { return tx().factory().buildEdgeElement(traversal.next()); } }
/** * @return a gremlin traversal that represents this inner query */ private GraphTraversal<Vertex, Map<String, Element>> getConjunctionTraversal( EmbeddedGraknTx<?> tx, GraphTraversal<Vertex, Vertex> traversal, Set<Var> vars, ImmutableList<Fragment> fragmentList ) { GraphTraversal<Vertex, ? extends Element> newTraversal = traversal; // If the first fragment can operate on edges, then we have to navigate all edges as well if (fragmentList.get(0).canOperateOnEdges()) { newTraversal = traversal.union(__.identity(), __.outE(Schema.EdgeLabel.ATTRIBUTE.getLabel())); } return applyFragments(tx, vars, fragmentList, newTraversal); }
/** * * @param direction The direction of the edges to retrieve * @param label The type of the edges to retrieve * @return A collection of edges from this concept in a particular direction of a specific type */ public Stream<EdgeElement> getEdgesOfType(Direction direction, Schema.EdgeLabel label){ Iterable<Edge> iterable = () -> element().edges(direction, label.getLabel()); return StreamSupport.stream(iterable.spliterator(), false). map(edge -> tx().factory().buildEdgeElement(edge)); }
@Override public GraphTraversal<Vertex, ? extends Element> applyTraversalInner( GraphTraversal<Vertex, ? extends Element> traversal, EmbeddedGraknTx<?> graph, Collection<Var> vars) { return Fragments.isVertex(traversal).in(RELATES.getLabel()); }
static <T> GraphTraversal<T, Vertex> outSubs(GraphTraversal<T, Vertex> traversal) { // These traversals make sure to only navigate types by checking they do not have a `THING_TYPE_LABEL_ID` property return union(traversal, ImmutableSet.of( __.<Vertex>not(__.has(THING_TYPE_LABEL_ID.name())).not(__.hasLabel(Schema.BaseType.SHARD.name())), __.repeat(__.out(SUB.getLabel())).emit() )).unfold(); }
@Override public GraphTraversal<Vertex, ? extends Element> applyTraversalInner( GraphTraversal<Vertex, ? extends Element> traversal, EmbeddedGraknTx<?> graph, Collection<Var> vars) { return Fragments.union(traversal, ImmutableSet.of( Fragments.isVertex(__.identity()).out(ISA.getLabel()).out(SHARD.getLabel()), edgeTraversal() )); }
@Override public GraphTraversal<Vertex, ? extends Element> applyTraversalInner( GraphTraversal<Vertex, ? extends Element> traversal, EmbeddedGraknTx<?> graph, Collection<Var> vars) { GraphTraversal<Vertex, Vertex> vertexTraversal = Fragments.outSubs(Fragments.isVertex(traversal)); if (required()) { return vertexTraversal.outE(PLAYS.getLabel()).has(Schema.EdgeProperty.REQUIRED.name()).otherV(); } else { return vertexTraversal.out(PLAYS.getLabel()); } }
static <T> GraphTraversal<T, Vertex> inSubs(GraphTraversal<T, Vertex> traversal) { // These traversals make sure to only navigate types by checking they do not have a `THING_TYPE_LABEL_ID` property return union(traversal, ImmutableSet.of( __.<Vertex>not(__.has(THING_TYPE_LABEL_ID.name())).not(__.hasLabel(Schema.BaseType.SHARD.name())), __.repeat(__.in(SUB.getLabel())).emit() )).unfold(); }
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(); }
/** * * @param to the target {@link VertexElement} * @param type the type of the edge to create * @return The edge created */ public EdgeElement addEdge(VertexElement to, Schema.EdgeLabel type) { tx().txCache().writeOccurred(); return tx().factory().buildEdgeElement(element().addEdge(type.getLabel(), to.element())); }
@Override public GraphTraversal<Vertex, ? extends Element> applyTraversalInner( GraphTraversal<Vertex, ? extends Element> traversal, EmbeddedGraknTx<?> graph, Collection<Var> vars) { GraphTraversal<Vertex, Vertex> vertexTraversal = Fragments.isVertex(traversal); if (required()) { vertexTraversal.inE(PLAYS.getLabel()).has(Schema.EdgeProperty.REQUIRED.name()).otherV(); } else { vertexTraversal.in(PLAYS.getLabel()); } return Fragments.inSubs(vertexTraversal); }