Search code examples
javagroovygremlintinkerpop3

Serialize DefaultGraphTraversal (from gremlin query) to GraphSON v3 json output


I'm using GremlinGroovyScriptEngine to eval a gremlin query (POSTed from REST api). The result of which returns a DefaultGraphTraversal object. I am trying to serialize this into a structure similar to

"result": {
    "data": {
        "@type": "g:List",
        "@value": [
            {
                "@type": "g:Vertex",
                "@value": {
                    "id": "Identity~1234567",
                    "label": "Identity",
                    "properties": {
                        "object_identifier": [
                            {
                                "@type": "g:VertexProperty",
                                "@value": {
                                    "id": {
                                        "@type": "g:Int32",
                                        "@value": -710449208
                                    },
                                    "value": "1234567",
                                    "label": "object_identifier"
                                }
                            }
                        ]
                    }
                }
            },
            .... more results here

I have tried using ObjectMapper like this

mapper = graph.io(GraphSONIo.build(GraphSONVersion.V3_0)).mapper.version(GraphSONVersion.V3_0).create.createMapper

and this ...

GraphSONMapper.build().
  addRegistry(com.lambdazen.bitsy.BitsyIoRegistryV3d0.instance()).
  version(GraphSONVersion.V3_0).create().createMapper()

and other variations of the above. Howerver, it gets deserialized to something like

{"@type":"g:List","@value":[]}

but the individual items of the list don't get serialized correctly.

Edit

Code example: gremlinQuery eg. g.V('id_12345')

List<Object> results = ((DefaultGraphTraversal<Vertex, Object>) this.engineWrite.eval(gremlinQuery, this.bindingsWrite)).toList();
ObjectMapper mapper = writeGraph.io(GraphSONIo.build(GraphSONVersion.V3_0))
                    .mapper()
                    .version(GraphSONVersion.V3_0)
                    .create()
                    .createMapper();
mapper.writeValueAsString(results);

which results in

{"@type":"g:List","@value":[]}

I have sort of got round this by iterating over the results and serializing thus:

List<Object> resList = new ArrayList<>();
results.stream().forEach(list -> resList.add(list));
String data = mapper.writeValueAsString(resList);

which does yield the correct results, but just seems like I'm missing something vital in order to be able to do it in one step.

What am I doing wrong here?? Many thanks


Solution

  • I'm not able to recreate the problem (along the 3.4.x line of code):

    gremlin> bindings = new javax.script.SimpleBindings()
    gremlin> bindings.put('g', TinkerFactory.createModern().traversal())
    gremlin> engine = new org.apache.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngine()
    ==>org.apache.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngine@7b676112
    gremlin> results = engine.eval("g.V(1)", bindings).toList()
    ==>v[1]
    gremlin> mapper = GraphSONMapper.build().version(GraphSONVersion.V3_0).create().createMapper()
    ==>org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper@7f5b9db
    gremlin> mapper.writeValueAsString(results)
    ==>{"@type":"g:List","@value":[{"@type":"g:Vertex","@value":{"id":{"@type":"g:Int32","@value":1},"label":"person","properties":{"name":[{"@type":"g:VertexProperty","@value":{"id":{"@type":"g:Int64","@value":0},"value":"marko","label":"name"}}],"age":[{"@type":"g:VertexProperty","@value":{"id":{"@type":"g:Int64","@value":1},"value":{"@type":"g:Int32","@value":29},"label":"age"}}]}}}]}
    

    The empty result would only be expected if the "result" itself was an empty list, but you seem to indicate that this is not the case given that iteration of the result and serialization of its contents seems to work just fine. I would suggest a few options to try to debug:

    1. Try to return the data as a Map using valueMap(true) and see what happens there. If it works then perhaps there is something wrong with the "BitsyIoRegistry"?
    2. I'd try both with and without valueMap(true) without "BitsyIoRegistry" included.
    3. Try all of this with TinkerGraph.

    If you can recreate the problem with TinkerGraph, then it's likely a problem with TinkerPop and will need to be addressed there. If it works for TinkerGraph then I assume it must be a problem with Bitsy somehow. Odd issue....