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..
Related
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.
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.
Based on the Modern Graph,
When I do a between search for a name, it seems to be case sensitive
gremlin> g.V().has("name", between("m", "mz")).values("name")
==>marko
gremlin> g.V().has("name", between("M", "Mz")).values("name")
gremlin>
I looked up but did not find a lower() or upper(), what I am trying to do is lower(x) == lower(y) so that the above becomes case in-sensitive.
You could or() the required conditions together:
gremlin> g = TinkerFactory.createModern().traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
gremlin> g.addV('person').property('name','Marvin')
==>v[13]
gremlin> g.addV('person').property('name','Marko')
==>v[15]
gremlin> g.V().or(has("name", between("Marko", "N")),has("name", between("marko", "n")))
==>v[1]
==>v[13]
==>v[15]
gremlin> g.V().or(has("name", between("Marko", "Markoz")),has("name", between("marko", "markoz")))
==>v[1]
==>v[15]
Just a warning - this approach works, but different graphs will treat this type of query differently. I don't know that all will optimize this type of query. If you're just experimenting on a small graph, then this approach might be fine, but you might not see the performance you want on a large graph depending on the traversal.
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]]