By-step with groovy does not extract values for some node - gremlin

The problem is described as following:
I want to find some interested paths and get corresponding properties of vertices or edges, the groovy I used is as following:
g.V().has("p_v_name", "d8e5d39d63c580acdb3eb188a1f4a942").
repeat(__.bothE().otherV().simplePath()).
times(3).emit().
has('p_v_tag').
path().
by(
__.project("label", "id", "p_v_black_tag").
by(__.label()).
by(__.id()).
by(__.choose(__.has('p_v_tag'),
__.properties('p_v_tag').project('value').by(__.value()).fold(),
__.constant([])
)
)
).unfold()
The above code gives me following result:
==>[label:v_user_key,id:749577404608,p_v_tag:[[value:PR016],[value:PR033],[value:PR068]]]
==>[label:e_application_id,id:4jjrk79js-9kcn170g-8ph-nvxhl4s0,p_v_tag:[]]
==>[label:v_application_id,id:1871880949872,p_v_tag:[]]
The result is unfolded for easing reading. It's just a path consisted of two nodes and one edge. The source node has a property p_v_tag, it's of multi-properties. The problem is the target node also has the property p_v_tag, but the code does not output the values.
I checked the target node has the property p_v_tag and it's not empty as following:
gremlin> g.V(1871880949872).properties('p_v_tag')
==>vp[p_v_tag->outdated]
I read the document(http://tinkerpop.apache.org/docs/current/reference) over and over but I can't figure out how to make it right, can any body help me or give me some advice?

I'm not sure why that wouldn't work. What happens if you try this workaround to replace:
by(__.choose(__.has('p_v_tag'),
__.properties('p_v_tag').project('value').by(__.value()).fold(),
__.constant([])
)
with:
by(coalesce(properties('p_v_tag').
project('value').
by(__.value()).
fold(),
constant([]))

Related

hasNot() having no effect

I'm using gremlin traversals via a Jupiter Notebook on Amazon Neptune.
I'm trying to filter edges from a specific vertex by their label, but it doesn't seem to work.
some sample data:
%%gremlin
g.addV().property(id, 'u0').as('u0').
addV().property(id, 'u1').as('u1').
addV().property(id, 'u2').as('u2').
addV().property(id, 'u3').as('u3').
addE('freind').
from('u0').
to('u1').
addE('buddy').
from('u0').
to('u2').
addE('foe').
from('u0').
to('u3').
iterate()
and my query:
(It is more complex than needed for this example, but my actual query repeats several times, therefore I can't simply use has('friend').has('buddy') because the next step has other labels.)
%%gremlin
g.withSack(1.0f).V('u0')
.repeat(
bothE().hasNot('foe')
.bothV())
.times(1)
.path().by().by(label)
output:
path[v[u0], freind, v[u1]]
path[v[u0], buddy, v[u2]]
path[v[u0], foe, v[u3]]
I have a user I start with (u0) and want all user who are his friends, buddies, and so on, but not his foes.
unfortunately its not filtering as its supposed to...
any Idea what I'm doing wrong?
The hasNot() step will only filter out elements that have a property with the specified name, in this case a property named foe. Instead, you should look at using not() with hasLabel() to find items that do not have a specific label, as shown here:
g.withSack(1.0f).V('u0')
.repeat(
bothE().not(hasLabel('foe'))
.bothV())
.times(1)
.path().by().by(label)

Gremlin with Neptune: filter edges using math result with previous edge value

I have the following graph:
And I want to solve the following traversal:
Start at node "abc-01-05"
Go to main "ip" node (id: abc)
Traverse out edges from ip node, where the date "at_millis" is less than the edge traversed in step 2 + 1 day
The result should be the nodes: abc-01-05 and abc-02-05
The best query I could make was based on this response, but doesn't work:
g.V('abc-01-05')
.outE('related_to').as_('saved_edge')
.inV()
.inE('related_to')
.where(
P.lte('saved_edge')
)
.by('at_millis')
.by(__.math('saved_edge + 86400001').by('at_millis'))
.toList()
This returns this error:
GremlinServerError: 500: {"requestId":"3aaaca37-75eb-4650-b111-130c6e65b040","code":"InternalFailureException","detailedMessage":"Exception processing a script on request [RequestMessage{, requestId=3aaaca37-75eb-4650-b111-130c6e65b040, op='bytecode', processor='traversal', args={gremlin=[[], [V(abc-01-05), outE(related_to), as(saved_edge), inV(), inE(related_to), where(lte(saved_edge)), by(at_millis), by([[], [math(saved_edge + 86400001), by(at_millis)]])]], aliases={g=g}}}]."}
Any help would be really helpful! Thanks!
Adding another answer just to point out that the error you were seeing with your original query was because the by steps need to be reversed. The second by modulator is applied to the label within the where step. The first by modulator defines what it will be compared to. Also, to get the test to work, the value being tested needs a minor tweak. Here is a working version of the original query.
g.V('abc-01-05')
.outE('related_to').as('saved_edge')
.inV()
.inE('related_to').as('related')
.where(P.lte('related'))
.by(__.math('saved_edge + 86400000').by('at_millis'))
.by('at_millis')
One way to do this :
g.V('abc-01-05').
outE('related_to').as('saved_edges').
values('at_millis').as('a1').
math('a1 + 86400001').as('saved_edges_millis_plus_1_day').
select('saved_edges').
inV().
inE('related_to').as('intermediate_edges').
values('at_millis').
where(P.lt('saved_edges_millis_plus_1_day')).
select('intermediate_edges')

Gremlin : How do you find vertex and edges when some edges does not exists

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.

Printing/Fetching Vertex values from a path

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.

Faunus graph not printing nodes without using side effect from gremlin shell

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.

Resources