I am calling JanusGraph remote, which returns ReferenceVertex by default. In order to retrieve properties as well, I use valueMap(), which works well for simple queries.
However, in my use case I need to build a join, which works well based on ReferenceVertex as follows:
// select t1.table2_ID, t2.table2_ID from table1 as t1 inner join table2 as t2 on t1.table2_ID = t2.table2_ID
GraphTraversal<?, ?> t1 = __.start().as("table1").out("relatesTo").hasLabel("table2").as("table2");
GraphTraversal<?, ?> t2 = g.V().hasLabel("table1").match(t1).select("table1", "table2");
List<?> l = t2.toList();
When adding valueMap to the traversal to retrieve the properties it fails. I want to include specific properties as follows:
// select t1.column1, t2.column2 from table1 as t1 inner join table2 as t2 on p.table2_ID = c.table2_ID
GraphTraversal<?, ?> t1 = __.start().as("table1").out("relatesTo").hasLabel("table2").valueMap(true, "column2").as("table2");
GraphTraversal<?, ?> t2 = g.V().hasLabel("table1").valueMap(true, "column1").match(t1).select("table1", "table2");
List<?> l = t2.toList();
-> java.util.HashMap cannot be cast to org.apache.tinkerpop.gremlin.structure.Element
Did I build the wrong traversal, or is this a limitation / bug in Tinkerpop?
Thank you
You can just modulate the select()
to apply valueMap()
to each column you return. Here's an example using the modern toy graph that ships with TinkerPop:
gremlin> g.V().as('a').out().as('b').select('a','b').by(valueMap())
==>[a:[name:[marko],age:[29]],b:[name:[lop],lang:[java]]]
==>[a:[name:[marko],age:[29]],b:[name:[vadas],age:[27]]]
==>[a:[name:[marko],age:[29]],b:[name:[josh],age:[32]]]
==>[a:[name:[josh],age:[32]],b:[name:[ripple],lang:[java]]]
==>[a:[name:[josh],age:[32]],b:[name:[lop],lang:[java]]]
==>[a:[name:[peter],age:[35]],b:[name:[lop],lang:[java]]]
so in your case you would just do:
GraphTraversal<?, ?> t1 = __.start().as("table1").out("relatesTo").hasLabel("table2").as("table2");
GraphTraversal<?, ?> t2 = g.V().hasLabel("table1").match(t1).select("table1", "table2").by(__.valueMap());
List<?> l = t2.toList();
That said, unless you've abbreviated your code a bit for purpose of this question, I'm not sure I see the need for match()
in this case. Seems like you could just simplify that to just:
List<?> l = g.V().hasLabel("table1").
out("relatesTo").hasLabel("table2").as("table2").
select("table1", "table2").
by(__.valueMap()).toList();