Just getting started with gremlin.
Printing out all the Vertex values worked out fine
gremlin> g.V().values()
==>testing 2
==>Cash Processing
==>Sales
==>Marketing
==>Accounting
I was able to find all the directly connected path between my Vertices.
gremlin> g.V().hasLabel('Process')
.repeat(both().simplePath())
.until(hasLabel('Process'))
.dedup().path()
==>[v[25],v[28]]
==>[v[25],v[26]]
==>[v[26],v[27]]
==>[v[26],v[25]]
Now am trying to print out the values in the path like ['Sales', 'Accounting'] instead of [v[25],v[28]]
Not been able to figure out a way yet
Already tried and failed with
Unfold: Does not get me 1-1 mapping
gremlin> g.V().hasLabel('Process').repeat(both().simplePath()).until(hasLabel('Process')).dedup().path().unfold().values()
==>Cash Processing
==>Accounting
==>Cash Processing
==>Sales
==>Sales
==>Marketing
==>Sales
==>Cash Processing
Path seems to be of a different data-type and does not support .values() function
gremlin> g.V().hasLabel('Process')
.repeat(both().simplePath())
.until(hasLabel('Process'))
.dedup().path().values()
org.apache.tinkerpop.gremlin.process.traversal.step.util.ImmutablePath cannot be cast to org.apache.tinkerpop.gremlin.structure.Element
Tried the following google searches and didnt get the answer
gremlin print a path
gremlin get values in a path
and few more word twisting
Found one at here that was for java but that didnt work for me
l = []; g.V().....path().fill(l)
(but cant create list, Cannot set readonly property: list for class: org.apache.tinkerpop.gremlin.structure.VertexProperty$Cardinality
)
I have running it on Gremlin console (running ./gremlin.sh)
You can use the by step to modulate the elements inside the path. For example by supplying valueMap(true) to by you get the properties of the vertices, together with the vertex labels and their ids:
gremlin> g.V().repeat(both().simplePath()).times(1).dedup().path().by(valueMap(true))
==>[[id:1,name:[marko],label:person,age:[29]],[id:3,name:[lop],lang:[java],label:software]]
==>[[id:1,name:[marko],label:person,age:[29]],[id:2,name:[vadas],label:person,age:[27]]]
==>[[id:1,name:[marko],label:person,age:[29]],[id:4,name:[josh],label:person,age:[32]]]
==>[[id:2,name:[vadas],label:person,age:[27]],[id:1,name:[marko],label:person,age:[29]]]
==>[[id:3,name:[lop],lang:[java],label:software],[id:6,name:[peter],label:person,age:[35]]]
==>[[id:4,name:[josh],label:person,age:[32]],[id:5,name:[ripple],lang:[java],label:software]]
I used the modern graph which is one of TinkerPop's toy graphs that are often used for such examples. Your output will look a bit different and you may want to use something else than valueMap(true) for the by modulator. The TinkerPop documentation of the path step itself contains two more advanced examples for path().by() that you might want to check out.
Related
I am new to gremlin.
I am facing issue in fetching the vertex and edges when sometimes edge from a vertex does not exists.
for example bellow query works fine if it gets all the vertex and edges.
but for one use case edge
`.outE("PRODUCES").`as`("produces"))`
does not exists in db.
in that case bellow query doesnt return any result.
I need your help to resolve this issue.
when edges does not exit then i want input_entity and processed_by in result.
janusGraph.traversal().V()
.has("isActive", "true")
.hasLabel("ENTITY").`as`("input_entity")
.outE("PROCESSED_BY").`as`("processed_by")
.inV().`as`("job")
.outE("PRODUCES").`as`("produces")
.select<String>("job").outE("HAS_STATE")
.`as`("job_state_edge").inV().hasLabel("JOB_STATE").`as`("job_state")
.select<String>("input_entity").outE("HAS_STATE")
.`as`("input_entity_state_edge").inV().hasLabel("ENTITY_STATE").`as`("input_entity_state")
.select<String>("input_entity").outE("CONNECTS_TO").`as`("connects_to")
.inV().hasLabel("ENTITY").has("entityName", TextP.startingWith(rootNamespace))
.`as`("output_entity").outE("HAS_STATE")
.`as`("output_entity_state_edge").inV().hasLabel("ENTITY_STATE").`as`("output_entity_state")
.select<String>("input_entity","output_entity","processed_by","produces","job","job_state","input_entity_state","output_entity_state","input_entity_state_edge","output_entity_state_edge","job_state_edge","connects_to")
.by(elementMap<Element, Any>()).toList()
with optional
janusGraph.traversal().V()
.has("isActive", "true")
.hasLabel("ENTITY").`as`("input_entity")
.outE("HAS_STATE").`as`("input_entity_state_edge").inV().hasLabel("ENTITY_STATE").`as`("input_entity_state")
.select<String>("input_entity").outE("PROCESSED_BY").`as`("processed_by")
.inV().`as`("job").outE("HAS_STATE").`as`("job_state_edge").inV().hasLabel("JOB_STATE").`as`("job_state")
.select<String>("job")
.optional(
outE("PRODUCES").`as`("produces")
.select<String>("input_entity").outE("CONNECTS_TO").`as`("connects_to")
.inV().hasLabel("ENTITY").has("entityName", TextP.startingWith(rootNamespace))
.`as`("output_entity").outE("HAS_STATE").`as`("output_entity_state_edge").inV().hasLabel("ENTITY_STATE").`as`("output_entity_state"))
.select<String>("input_entity","output_entity","processed_by","produces","job","job_state","input_entity_state","output_entity_state","input_entity_state_edge","output_entity_state_edge","job_state_edge","connects_to")
.by(elementMap<Element, Any>()).toList()
There are two Gremlin steps that can help in cases like this. When you have a part of a query that may or may not exist, but you either want the results up to that point if it does not exist or the results afterwards if it does exist, you can wrap that part of the query in an optional step.
For example :
g.V('3').optional(out())
Will either return V['3'] or the adjacent vertices if out yields results.
In cases where you want to select a value that may not exist, you can do something like this:
coalesce(select('a'),constant('No results'))
EDITED to add:
If you need to return multiple results, rather than just using select try a project('a','b,',c') type of approach where each by modulator for the project can contain its own coalesce step.
I am trying to write a gremlin query to get all the edges between a list of vertices.
Data redacted to protect privacy. User A(42651832) -reports_to-> User
B(28729440) -reports_to-> User C(19546208)
ids = [19546208, 28729440, 42651832]
I need to find all the edges between an arbitrary list of vertices
Seems simple, but I am unable to write a query that gives results I need.
gremlin> g.V(42651832).outE('reports_to').otherV().id()
==>28729440
gremlin> g.V(28729440).outE('reports_to').otherV().id()
==>19546208
gremlin> ids = [19546208, 28729440, 42651832]
==>19546208
==>28729440
==>42651832
gremlin> g.V(ids)
==>v[19546208]
==>v[28729440]
==>v[42651832]
gremlin> g.V(ids).bothE().where(otherV().hasId(ids))
gremlin> g.V(ids).bothE().where(otherV().hasId(within(ids)))
gremlin> g.V(ids).bothE().where(otherV().hasId(within(19546208, 28729440, 42651832)))
Apparently, I think there is a type conversion issue between gremlin console and JanusGraph.
quoting as string or converting to Long seems to work.
gremlin> g.V(ids).bothE().where(otherV().hasId(within("19546208", "28729440", "42651832")))
==>e[10r7d8-h3rs0-i6t-bmxy8][28729440-reports_to->19546208]
==>e[10r7d8-h3rs0-i6t-bmxy8][28729440-reports_to->19546208]
==>e[128qvr-pe6d4-i6t-h3rs0][42651832-reports_to->28729440]
==>e[128qvr-pe6d4-i6t-h3rs0][42651832-reports_to->28729440]
gremlin> g.V(ids).bothE().where(otherV().hasId(within(19546208L, 28729440L, 42651832L)))
==>e[10r7d8-h3rs0-i6t-bmxy8][28729440-reports_to->19546208]
==>e[10r7d8-h3rs0-i6t-bmxy8][28729440-reports_to->19546208]
==>e[128qvr-pe6d4-i6t-h3rs0][42651832-reports_to->28729440]
==>e[128qvr-pe6d4-i6t-h3rs0][42651832-reports_to->28729440]
gremlin>
gremlin> g.V(ids).bothE().where(otherV().hasId(within(19546208L, 28729440L, 42651832L))).dedup()
==>e[10r7d8-h3rs0-i6t-bmxy8][28729440-reports_to->19546208]
==>e[128qvr-pe6d4-i6t-h3rs0][42651832-reports_to->28729440]
Any other suggestions. Not sure why JanusGraph works this way.
This isn't quite a full answer, but hopefully it gets you close enough. I used GraphOfTheGods to test it out.
This will get all the paths from the ids list to the quoted ids in hasID() and then output a list of all the edges traversed in each path. I added a limit for readability. You could easily add all the values to a set to get a deduped answer.
# Save all the graph of the gods vertex ids to a variable
ids = [4112,4128,4136,8232,12328,16424,20520,4296,4328,4344,8440,12536]
paths = g.V(ids).until(hasId("8440","12536")).repeat(bothE().aggregate("e").otherV().simplePath()).limit(3).select('e')
==>[e[74v-6ig-9hx-368][8440-battled->4112]]
==>[e[74v-6ig-9hx-368][8440-battled->4112],e[7xb-6ig-9hx-36o][8440-battled->4128],e[1l0-36o-b2t-9o8][4128-lives->12536],e[9vp-co8-bv9-36o][16424-pet->4128]]
==>[e[74v-6ig-9hx-368][8440-battled->4112],e[7xb-6ig-9hx-36o][8440-battled->4128],e[1l0-36o-b2t-9o8][4128-lives->12536],e[9vp-co8-bv9-36o][16424-pet->4128]]
What I was able to originally get was a full path with connecting vertexes which I am including in case it could potentially be helpful.
paths = g.V(ids).until(hasId("8440","12536")).repeat(bothE().otherV().simplePath()).path().limit(5)
==>[v[4112],e[74v-6ig-9hx-368][8440-battled->4112],v[8440]]
==>[v[4128],e[7xb-6ig-9hx-36o][8440-battled->4128],v[8440]]
==>[v[4128],e[1l0-36o-b2t-9o8][4128-lives->12536],v[12536]]
==>[v[4128],e[9vp-co8-bv9-36o][16424-pet->4128],v[16424],e[9hh-co8-b2t-9o8][16424-lives->12536],v[12536]]
==>[v[4128],e[9vp-co8-bv9-36o][16424-pet->4128],v[16424],e[8p1-co8-cnp-3co][16424-brother->4344],v[4344],e[6cf-6ig-7x1-3co][8440-father->4344],v[8440]]
Separately I did some checking with the GraphOfTheGods and the explain() step and it definitely seems like a bug. If I set a list to variable it is performing an equal step instead of a within step.
paths = g.V(ids).until(hasId(ids)).repeat(out().simplePath()).limit(10).path().explain()
...RepeatStep(until([HasStep([~id.eq([4112, 4128, ...])])]),
where as listing in quotes it will properly do a within check.
paths = g.V(ids).until(hasId("8440","12536")).repeat(outE().simplePath()).limit(10).path().explain()
...RepeatStep(until([HasStep([~id.within([8440, 12536])])])
I am trying to execute a gremlin script over https against a remote JanusGraph instance. I have filtered my problem to the part where I am trying to add an edge using vertex variables. I am trying to add two vertices, assign the results to a variable and use them to add an edge. Also I am also tying to avoid a single line script like g.V().addV(..).aaddV(..).addE(..), because of the program logic that is behind the script
The following gremlin works in the gremlin console (remote session)
def graph=ConfiguredGraphFactory.open("ga");
def g = graph.traversal();
v1=g.addV('node1');
v2=g.addV('node2');
v1.addE('test').to(v2);
But when I try to do the same over https (issued against a compose-janusgraph server), I get an error. I did add .iterate() to the addV() and the vertexes are getting added if I remove the addE(..) line. But when I try
{"gremlin":"def graph=ConfiguredGraphFactory.open('ga');
def g = graph.traversal();
v1=g.addV('node16').property('name','testn16').iterate();
v2=g.addV('node17').property('name','testn2').iterate();
v1.addE('test18').to(v2);
g.tx().commit()"}
I get the exception
The traversal strategies are complete and the traversal can no longer
be modulated","Exception-Class":"java.lang.IllegalStateException"
Also note that I am joining the whole gremlin into one single line before sending it over curl. I have split them to newlines here for readability. Any help would be great. -- Thank you
iterate() doesn't return a Vertex...it just iterates the traversal to generate side-effects (i.e. the graph gets a vertex added but no result is returned). You probably just need to do:
{"gremlin":"graph=ConfiguredGraphFactory.open('ga');
g = graph.traversal();
g.addV('node16').property('name','testn16').as('v1').
addV('node17').property('name','testn2').as('v2').
addE('test18').from('v1').to('v2').iterate();
g.tx().commit()"}
The following query of the Titan example graph does not produce what I expected:
g.V.has("age", T.lte,1000).as('young').out('battled').has("name","cerberus").copySplit(
_().back('young'),
_()
).exhaustMerge
it gives me twice the cerberus vertex, instead of hercules and cerberus
It appears that back is not working after a copySplit. Is there a way around this limitation?
Already answered on the Gremlin users mailing list, but here we go again:
These 2 alternatives would still work in Gremlin3 (with a slightly different syntax, but the concept is the same):
gremlin> g.V().has("age", T.lte, 1000).as("young").out("battled").has("name", "cerberus").as("monster").select()
==>[young:v[24], monster:v[44]]
Or:
gremlin> g.V().has("age", T.lte, 1000).out("battled").has("name", "cerberus").path()
==>[v[24], v[44]]
I'm trying to print a graph in Faunus (v0.4.0) where a node has any edges (incoming or outgoing). From the gremlin shell, I tried:
g = FaunusFactory.open('faunus.properties')
g.V.filter("{it.bothE.hasNext()}").sideEffect("{println it}")
When I do this, I get a printout of all the nodes as I expected
But without the println, I do not.
According to How do I write a for loop in gremlin?, the gremlin terminal should print this info out for me, but it does not seem to.
Is there something specific I need to do to enable the printing from the console?
Faunus and Gremlin are close to each other in terms of purpose and functionality but not identical. The filter isn't producing a side-effect, which will be written to HDFS. If you did:
g.V.filter("{it.bothE.hasNext()}").id
You could then view the list of ids matching that filter with something like:
hdfs.head('output',100)
to see the first 100 lines of the output. If you need more than just the element identifier you could do a transform to get some of the element properties in there as well. You might find these hdfs helper tips helpful.