问题
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
回答1:
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();
来源:https://stackoverflow.com/questions/53621774/using-valuemap-with-match