Search code examples
c#tinkerpopgremlin-serverazure-cosmosdb-gremlinapigremlinnet

Extract subgraph from a graph using Gremlin.net byte code gives error deserializer for \"tinker:graph\" not found


I am trying to get subgraph from a graph using Gremlin.net bytecode syntax and getting error when extracting/Cap from a subgraph. I am able to get the results if I query directly using the query string however not with the fluent API byte code syntax.

Query string that returns results when used directly on cosmos DB:

g.V().has('name','Samplevertex').outE().HasLabel("child").subgraph('sg').cap('sg')

C# gremlin.net syntax that is not working is :

var result = g
                    .V()
                    .Has("name", "Samplevertex")
                    .OutE()
                    .HasLabel("child")
                    .Subgraph("sg")
                    .Cap<GraphSON3Reader>("sg")
                    .Next();

When I use the above code it gives an error saying that deserializer for "tinker:graph" not found. Tried with different types in Cap<> like string , custom model. however still got the same error.

Want to know if I am missing anything from Gremlin server config side or if there is a known issue that subgraphs with cap do not work with gremlin.net by default ?

I have the following settings in my gremlin server yaml: enter image description here


Solution

  • I was able to solve this by creating my own custom Deserializer as I learnt that we currently dont have other options for queries that returned Graph.

    Followed the steps from http://tinkerpop.apache.org/docs/3.2.6/reference/#_custom_serialization_2

    Used the new class name in the Cap<> command used in the bytecode and got the results.

    **Following is the snippet:**
    internal class MySubgraph
        {
            public static string GraphsonPrefix = "tinker";
            public static string GraphsonBaseType = "graph";
            public static string GraphsonType = GraphSONUtil.FormatTypeName(GraphsonPrefix, 
        GraphsonBaseType);
    
            public MySubgraph(ICollection<IVertex> vertices, ICollection<IEdge> edges)
            {
                Vertices = vertices;
                Edges = edges;
            }
    
            public ICollection<IVertex> Vertices { get; }
            public ICollection<IEdge> Edges { get; }
    }
    
    
    
        internal class MySubgraphReader : IGraphSONDeserializer
        {
            public dynamic Objectify(JToken graphsonObject, GraphSONReader reader)
            {
                JToken jVertices = graphsonObject["vertices"];
                dynamic vertices = reader.ToObject(graphsonObject["vertices"]);
    
                // Custom deserialization logic here 
            }
        }
    

    Byte code needs to be used like this :

    var result = g
                        .V()
                        .Has("name", "Samplevertex")
                        .OutE()
                        .HasLabel("child")
                        .Subgraph("sg")
                        .Cap<MySubgraph>("sg")
                    .Next();