I have a simple graph with two vertices, having ids 'a' and 'b'.
I have assigned an edge from 'a' to 'b' with label = 'foo'
gremlin> g.V()
==>v[b]
==>v[a]
gremlin> g.E()
==>e[04b4b9fd-2f20-751d-5673-5aa9d7ce0285][a-foo->b]
My question: how do I traverse backwards along the same edge? For example, if a query traverses to an outbound vertex, how can that query then traverse back across the same edge to the inbound vertex?
My query is shown below:
g.E('04b4b9fd-2f20-751d-5673-5aa9d7ce0285').outV().as('outV')...[want to get the inV for the same edge, here]
There's a lot of different ways to do this. Here's a few that will hopefully inspire you to your answer. You probably shouldn't count on the order in which the vertices are returned in the following case, but you could do bothV():
gremlin> g.E(11).bothV()
==>v[4]
==>v[3]
To force order you could do a union():
gremlin> g.E(11).union(inV(),outV())
==>v[3]
==>v[4]
You could always project() your results:
gremlin> g.E(11).project('in','out').by(inV()).by(outV())
==>[in:v[3],out:v[4]]
If you need to do something with the outV() first and then come back to the edge after that to then traverse on inV() you could label the E() step with as():
gremlin> g.E(11).as('e').outV().hasLabel('person').select('e').inV()
==>v[3]
Hopefully, those examples help.
Related
I'm trying to query for edges that go to vertices within an aggregated list. It sounds quite simple, and it should be, but I seem to be writing my queries wrong, and I just can't figure out why. Anyway, I'll use the Modern Toy Graph to make an example, that won't necessarily make much sense in this context, but still illustrates what I wish to do:
graph = TinkerFactory.createModern()
g = graph.traversal()
g.V().
hasLabel('person').
aggregate('x').
outE().
where(inV().is(within('x')))
What I'm doing is traversing to all 'person' vertices, aggregating them, then trying to get all the outgoing edges that lead to another vertex within that aggregated list. I expect the above query to return the edge labelled "knows" that goes between vertex 1 and 2, and the one between 1 and 4, however nothing is returned. If i simple want to get the vertices on the other end of those edges, rather than the edges themselves, the following works fine, returning vertex 2 and 4:
g.V().
hasLabel('person').
aggregate('x').
out().
where(within('x'))
So how can I get edges that lead to vertices already aggregated in a list?
(Once again, I'm aware this example doesn't make much sense within this particular graph, and I could easily query outE('knows'), but this query is relevant to a different graph.)
Thanks.
You can't use is() quite that way. An easy fix would be to just combine your "working" traversal with the one that doesn't:
gremlin> g.V().hasLabel('person').
......1> aggregate('x').
......2> outE().
......3> where(inV().where(within('x')))
==>e[7][1-knows->2]
==>e[8][1-knows->4]
I need help with a Gremlin query that can output all the vertices related to one specific vertex A and their cascading related vertices (which means all the vertices related directly or indirectly to A).
For example, in a graph
A -> B -> C
D
Running this query on A will give me B and C.
The solution I have right now is an ugly one:
g.V('A').both(); g.V('A').both().both();
etc
Any help would be really appreciated.
Your solution isn't ugly; it only lacks a bit of iteration and an exit condition.
Do you require a maximum depth? Depending on the shape of your graph, the query you want to execute could be returning all vertices of that graph.
Assuming a toy modern TinkerGraph created in the Gremlin console:
gremlin> graph = TinkerFactory.createModern()
==>tinkergraph[vertices:6 edges:6]
gremlin> g = graph.traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
This query could be helpful:
gremlin> g.V(1).repeat(both().simplePath()).emit().times(3).dedup()
==>v[3]
==>v[2]
==>v[4]
==>v[6]
==>v[5]
"Starting from vertex with id=1, traverse the graph in all directions up to a maximum depth of 3 while discarding previously visited paths. The emit() step ensures that all traversed vertices found along the way, and not just leaves, are returned."
Chances are high that you want to figure out which vertices are linked to that vertex only via specific edges. In such case, you could be passing label(s) to the both() step, and/or maybe chain a few filters.
When developing your query, feel free to chain the path() step to better understand the output.
gremlin> g.V(1).repeat(both().simplePath()).emit().times(3).dedup().path()
==>[v[1],v[3]]
==>[v[1],v[2]]
==>[v[1],v[4]]
==>[v[1],v[3],v[6]]
==>[v[1],v[4],v[5]]
There are other ways to solve this, but this query should get you started and familiarize yourself with basic Gremlin steps and concepts.
I was trying to run a gremlin query to find k distance vertices from a given vertex v and omit directly connected vertices to v.
I am using Gremlin 3.2.6.
So, something like this, for a k-distance(friend of friend) isn't working properly
g.V(v).both().as(“x”).repeat(both()).times(k).where(neq("x")).dedup()
The above should omit the vertices in "x" but it is not.
My graph is directed and there may be edges in both directions between a pair of vertices.
Also, how do I make this general for given distances less than some k using loops(having a hard time with it) and is there some way to print the distance along with the vertex list. Thanks.
x should actually be an aggregation of all adjacent vertices, not just a reference to the adjacent vertex on the current path.
gremlin> g = TinkerFactory.createModern().traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
gremlin> g.V(1).both().aggregate("x").
repeat(both().dedup()).
times(5).
emit().
where(without("x"))
==>v[1]
==>v[6]
==>v[5]
And if you also want to exclude the start vertex, just add it to the collection:
gremlin> g.V(1).store("x").
both().aggregate("x").
repeat(both().dedup()).
times(5).
emit().
where(without("x"))
==>v[6]
==>v[5]
I have the following Graph
If I write a Query g.V('A').Out(), how can I get that the values of the Edges which were traversed and the vertex which were encounterned in the traveral ?
You would need to tell Gremlin to not skip the edges. g.V().out() is shorthand for g.V().outE().inV(). In this case, you can interact with the value of the edges as you've explicitly told Gremlin to traverse them. I'll demonstrate with a few examples using the "modern" toy graph:
gremlin> g = TinkerFactory.createModern().traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
To start, you might want to filter on a particular edge property and then traverse to adjacent vertices:
gremlin> g.V().outE().has('weight',gt(0.5)).inV()
==>v[4]
==>v[5]
You mentioned in your question that you might want to see the values of edges and the vertices you encountered. One way would be to use path():
gremlin> g.V().outE().has('weight',gt(0.5)).inV().path()
==>[v[1],e[8][1-knows->4],v[4]]
==>[v[4],e[10][4-created->5],v[5]]
You might also get more explicit to get specific properties from the edge:
gremlin> g.V().outE().has('weight',gt(0.5)).inV().path().by().by('weight')
==>[v[1],1.0,v[4]]
==>[v[4],1.0,v[5]]
I want to look for a vertex, get an edge 'views', remove it, and replace with a new edge between the same vertices.
g.V('uuid','bf4dcbd24e9944319954dec5ad60c658')
.inE('views')
.sideEffect{g.addEdge(it.outV.next(),it.inV.next(),'likes')}
.sideEffect{g.removeEdge(it)}
This works, but is it the best way? Renaming the edge is an option?
You can use sideEffect as you did. That approach has the positive aspect of being straightforward and easy to understand. However, my personal preference for "production" Gremlin code is to use explicit Gremlin functions when they are available. In this case, I see the opportunity to use "link" and "step closures" (https://github.com/tinkerpop/gremlin/wiki/Step-Closures):
gremlin> g = TinkerGraphFactory.createTinkerGraph()
==>tinkergraph[vertices:6 edges:6]
gremlin> g.E
==>e[10][4-created->5]
==>e[7][1-knows->2]
==>e[9][1-created->3]
==>e[8][1-knows->4]
==>e[11][4-created->3]
==>e[12][6-created->3]
gremlin> g.v(1).as('x').outE('knows').as('toRemove').inV.except('x').linkIn('swonk','x').sideEffect{v,m->g.removeEdge(m.toRemove)}
==>v[2]
==>v[4]
gremlin> g.E
==>e[1][1-swonk->4]
==>e[10][4-created->5]
==>e[0][1-swonk->2]
==>e[9][1-created->3]
==>e[11][4-created->3]
==>e[12][6-created->3]
In the above I "rename" all the "knows" edges for g.v(1) to "swonk".
fixed the first error before queston eddit.
Done...
g.V('uuid','bf4dcbd24e9944319954dec5ad60c658')
.inE('views')
.sideEffect{g.addEdge(it.outV.next(),it.inV.next(),'likes')}
the .next() fixed the script..