Franco Cuevas
Franco Cuevas

Reputation: 91

Gremlin: getting json response in Java with gremlin-driver

I have the following query:

  g
    .V("user-11")
    .repeat(bothE().subgraph("subGraph").outV())
    .times(2)
    .cap("subGraph")
    .next()

When I run it using gremlin-python, I receive the following response:

{'@type': 'tinker:graph',
 '@value': {'vertices': [v[device-3], v[device-1], v[user-11], v[card-1]],
  'edges': [e[68bad734-db2b-bffc-3e17-a0813d2670cc][user-11-uses_device->device-1],
   e[14bad735-2b70-860f-705f-4c0b769a7849][user-11-uses_device->device-3],
   e[f0bb3b6d-d161-ec60-5e6d-068272297f24][user-11-uses_card->card-1]]}}

Which is a Graphson representation of the subgraph obtained by the query.

I want to get the same response using Java and gremlin-driver but I haven't been able to figure how.

My best try was:

ObjectMapper mapper = GraphSONMapper.build().version(GraphSONVersion.V3_0).create().createMapper();
Object a = graphTraversalSource
                .V(nodeId)
                .repeat(bothE().subgraph("subGraph").outV())
                .times(2)
                .cap("subGraph")
                .next();
return mapper.writeValueAsString(a);

But that gave me the following error:

io.netty.handler.codec.DecoderException: org.apache.tinkerpop.gremlin.driver.ser.SerializationException: org.apache.tinkerpop.shaded.kryo.KryoException: Encountered unregistered class ID: 65536

I am using AWS Neptune, but I doubt that makes a difference given that I receive the answer I want through gremlin-python.

I appreciate any help you can give! Thanks

Upvotes: 0

Views: 1180

Answers (1)

Kelvin Lawrence
Kelvin Lawrence

Reputation: 14371

As mentioned in the comments

  1. When using Java what you get back will be an actual TinkerGraph
  2. Using the GraphBinary or GraphSONV3D0 serializer is recommended.

The Gyro one is older and is likely causing the error you saw if you did not specify one of the others serializers.

Note that even if you use one of the other serializers, to get the graph to deserialize into JSON you will need to use the specific TinkerGraph serializer (see the end of this answer for an example). Otherwise you will just get {} returned.

However, you may not need to produce JSON at all in the case of the Java Gremlin client ....

Given you have an actual TinkerGraph back you can run real Gremlin queries against the in-memory subgraph - just create a new traversal source for it. You can also use the graph.io classes to write the graph to file should you wish to. The TinkerGraph will include properties as well as edges and vertices.

You can also access the TinkerGraph object directly using statements such as

a.vertices and a.edges

By means of a concrete example, if you have a query of the form

TinkerGraph tg = (TinkerGraph)g.V().bothE().subgraph("sg").cap("sg").next();

Then you can do

GraphTraversalSource g2 = tg.traversal();

Long cv = g2.V().count().next();
Long ce = g2.E().count().next();

Or you can just access the TinkerGraph data structure directly using statements of the form:

Vertex v = tg.vertices[<some-id>]

Or

List properties = tg.vertices[<some-id>].properties()

This actually means you have a lot more power available to you in the Java client when working with subgraphs.

If you still feel that you need a JSON version of your subgraph, the IO reference is a handy bookmark to have: https://tinkerpop.apache.org/docs/3.4.9/dev/io/#_io_reference

EDITED: - to save you a lot of reading the docs, this code will print a TinkerGraph as JSON

mapper = GraphSONMapper.build().
            addRegistry(TinkerIoRegistryV3d0.instance()).
            version(GraphSONVersion.V3_0).create().createMapper();

mapper.writeValueAsString(tg) 

Upvotes: 2

Related Questions