Search code examples
javatitangremlintinkerpop3

Titan gremlin console and java returns different result for group().by() query


I am using Titan 1.0.0 supported by cassandra 2.1.7 as backend storage. While trying to execute the same query on gremlin console and java program, I am getting 2 the output in two different formats. I am using the gremlin console provided by titan-1.0.0-hadoop1 and for java I am using TinkerPop Gremlin 3.0.1-incubating.

Gremlin Console:

gremlin> g.V().has('msid',within(-2128958273, 2147477890)).as('in').local(outE('hie_child').has('hostid_e',within(153,83)).order().by('hrank',incr).limit(5)).group().by(outV().id()).by(inV().id().fold())

==>[77467688:[1531850904, 4742561976, 1009049792, 1010020408, 1053356264], 73363640:[2060075072, 3698942184, 6776295608, 7030726848, 35401920]]

I am getting the expected type of output i.e. Map<VertexId, List<VertexId>>

But while executing the same query in java program, I am getting Map<VertexId, BulkSet>. The BulkSet includes a counter indicating the number of times a particular entry is added in the result set. Can someone please tell me if there is a way to get the similar result in java as gremlin console.

Java:

List<Map<Object, Object>> list = g.V().has("msid", P.within(-2128958273,2147477890)).as("in").local(__.outE("hie_child").has("hostid_e", P.within(153,83)).order().by("hrank", Order.incr).limit(5)).group().by(__.outV().id()).by(__.inV().id().fold()).fold().next();

System.out.println(list);

[{77467688={1531850904=1, 4742561976=1, 1009049792=1, 1010020408=1, 1053356264=1}, 73363640={2060075072=1, 3698942184=1, 6776295608=1, 7030726848=1, 35401920=1}}]


Solution

  • See answer given here https://stackoverflow.com/a/43284707/5025129

    • iterate() get zero result
    • next() get one result
    • toList() get many results

    You should call on toList() rather than next().

    This is also a good read on result iteration http://tinkerpop.apache.org/docs/current/tutorials/the-gremlin-console/#result-iteration

    EDIT: There appears to be a bug in TinkerPop 3.0.x related to this, and it is reproducible in the Gremlin Console, but it is fixed in TinkerPop 3.1.x. Actually, you should be able to use the BulkSet just fine as it only contains values. What you're seeing is the difference in the BulkSet.toString() vs ArrayList.toString().

    TinkerPop 3.0.x

    gremlin> graph = TinkerFactory.createModern()
    ==>tinkergraph[vertices:6 edges:6]
    gremlin> g = graph.traversal()
    ==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
    gremlin>  l = g.V(1).local( outE('knows') ).group().by( __.outV().id() ).by( __.inV().id().fold() ).fold().next()
    ==>[1:[2, 4]]
    gremlin> l[0].getClass()
    ==>class org.apache.tinkerpop.gremlin.process.traversal.step.map.GroupStep$GroupMap
    gremlin> l[0].values().iterator().next().getClass()
    ==>class org.apache.tinkerpop.gremlin.process.traversal.step.util.BulkSet
    gremlin> bs = l[0].values().iterator().next()
    ==>2
    ==>4
    gremlin> bs[0].getClass()
    ==>class java.lang.Integer
    gremlin> bs[1].getClass()
    ==>class java.lang.Integer
    gremlin> bs.toString()
    ==>{2=1, 4=1}
    

    TinkerPop 3.1.x

    gremlin> graph = TinkerFactory.createModern()
    ==>tinkergraph[vertices:6 edges:6]
    gremlin> g = graph.traversal()
    ==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
    gremlin>  l = g.V(1).local( outE('knows') ).group().by( __.outV().id() ).by( __.inV().id().fold() ).fold().next()
    ==>[1:[2, 4]]
    gremlin> l[0].getClass()
    ==>class java.util.HashMap
    gremlin>  l[0].values().iterator().next().getClass()
    ==>class java.util.ArrayList
    gremlin> bs = l[0].values().iterator().next()
    ==>2
    ==>4
    gremlin> bs[0].getClass()
    ==>class java.lang.Integer
    gremlin> bs[1].getClass()
    ==>class java.lang.Integer
    gremlin> bs.toString()
    ==>[2, 4]
    

    You could build the titan11 branch which uses TinkerPop 3.1.1 or you could try JanusGraph.