Returning Janus Edges using Gremlin.NET - workaround not working with Promises


shapesh...@...
 

I found out a while ago that returning edges from Janus is a problem with gremlin.net as you get this exception:

"Deserializer for \"janusgraph:RelationIdentifier\" not found"

As I don't have the time or knowledge for writing custom serialisers or similar, I have been using a semi-satisfactory work-around of

g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId)).Values<string>().Next();

This adds the edge just fine, although I have nothing returned to prove it (can't work out how to return the id)

However, I have been asked to convert all my code to use Promises (as defined in ITraversal).  This has worked just fine with Vertex-based traversals, but I'm back to square one with Edges in that no matter what I try I get that damn exception again.

Here's a little of my (admittedly flakey) code:

var graphTrav = g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId));

// attempt 1
var result = await graphTrav.Promise<ITraversal>(traverse);

Func<ITraversal<Vertex, Edge>, ITraversal> traverse =
(trav) =>
{
    return trav.Iterate();
};

I cannot use values() on an itraversal object so trying iterate() to try and avoid a return object(?). Still get the exception


// attempt 2
var result = await graphTrav.Promise<string>(traverse);

Func<ITraversal<Vertex, Edge>, string> traverse =
(trav) =>
{
    GraphTraversal<Vertex, Edge> gt = (GraphTraversal<Vertex, Edge>)trav;
    return gt.Values<string>().Next();
};

here I've tried creating a GraphTraversal out of the Itraversal object. Janus stores the edge, but gives the exception even though it is meant to return a string like my work-around

I guess this may be more of a C# query than a gremlin(.net) one, but I would appreciate any help please.



shapesh...@...
 

Apologies for not posting this in the user's group where I guess is where it should have gone.

Anyway, I've part-fixed my own problem by changing the initial traversal to:

g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId)).Values<string>();

which meant the following change:

Func<ITraversal<Vertex, String>, string> traverse =
                (trav) =>
                {
                    return trav.Next();
                };

Still can't return the id of the new edge though. Can't just return .id() as the resulting I/graphtraversal would be <vertex, object> and anything bar <vertex. string> causes the exception.


On Wednesday, 27 June 2018 15:32:35 UTC+1, Richard Moss wrote:
I found out a while ago that returning edges from Janus is a problem with gremlin.net as you get this exception:

"Deserializer for \"janusgraph:RelationIdentifier\" not found"

As I don't have the time or knowledge for writing custom serialisers or similar, I have been using a semi-satisfactory work-around of

g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId)).Values<string>().Next();

This adds the edge just fine, although I have nothing returned to prove it (can't work out how to return the id)

However, I have been asked to convert all my code to use Promises (as defined in ITraversal).  This has worked just fine with Vertex-based traversals, but I'm back to square one with Edges in that no matter what I try I get that damn exception again.

Here's a little of my (admittedly flakey) code:

var graphTrav = g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId));

// attempt 1
var result = await graphTrav.Promise<ITraversal>(traverse);

Func<ITraversal<Vertex, Edge>, ITraversal> traverse =
(trav) =>
{
    return trav.Iterate();
};

I cannot use values() on an itraversal object so trying iterate() to try and avoid a return object(?). Still get the exception


// attempt 2
var result = await graphTrav.Promise<string>(traverse);

Func<ITraversal<Vertex, Edge>, string> traverse =
(trav) =>
{
    GraphTraversal<Vertex, Edge> gt = (GraphTraversal<Vertex, Edge>)trav;
    return gt.Values<string>().Next();
};

here I've tried creating a GraphTraversal out of the Itraversal object. Janus stores the edge, but gives the exception even though it is meant to return a string like my work-around

I guess this may be more of a C# query than a gremlin(.net) one, but I would appreciate any help please.



Florian Hockmann <f...@...>
 

You say that you want to return the edge id to prove that it was actually created. Before talking about how you can fix this problem I just want to mention that you don't really need to prove that as you would get an exception if something went wrong. So, when you don't get an exception then the edge was created.

If you nevertheless want to return the edge id then you currently don't have any other option than implementing an edge id deserializer. I recently implemented a library for JanusGraph which extends Gremlin.Net and handles the serialization and deserialization of JanusGraph specific types (and also JanusGraph's search predicates) for you. This library is currently in review and should be added to JanusGraph itself but that will take some time. Until then, you can simply use the code from that pull request in your own project. Here are the relevant classes:

RelationIdentifierSerializer (only needed when you also want to search edges by their id)

Then you can use those classes to configure the serialization when you create the GremlinClient like this:

var reader = new GraphSON2Reader(new Dictionary<string, IGraphSONDeserializer>
   
{
       
{"janusgraph:RelationIdentifier", new RelationIdentifierDeserializer()}
   
});

var writer = new GraphSON2Writer(new Dictionary<Type, IGraphSONSerializer>
   
{
       
{typeof(RelationIdentifier), new RelationIdentifierSerializer()}
   
});

var client = new GremlinClient(_server, reader, writer, GremlinClient.GraphSON2MimeType);

(Note, the GraphSON2 specific aspects are only necessary when you use Gremlin.Net in a version of 3.3.0 or higher as Gremlin.Net then uses GraphSON3 by default which isn't supported by JanusGraph 0.2.0.)

BTW: You can also express the way you use the Promise step a bit easier like this:
var id = await g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId)).Id().Promise(t => t.Next());

Am Mittwoch, 27. Juni 2018 18:26:09 UTC+2 schrieb Richard Moss:

Apologies for not posting this in the user's group where I guess is where it should have gone.

Anyway, I've part-fixed my own problem by changing the initial traversal to:

g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId)).Values<string>();

which meant the following change:

Func<ITraversal<Vertex, String>, string> traverse =
                (trav) =>
                {
                    return trav.Next();
                };

Still can't return the id of the new edge though. Can't just return .id() as the resulting I/graphtraversal would be <vertex, object> and anything bar <vertex. string> causes the exception.


On Wednesday, 27 June 2018 15:32:35 UTC+1, Richard Moss wrote:
I found out a while ago that returning edges from Janus is a problem with gremlin.net as you get this exception:

"Deserializer for \"janusgraph:RelationIdentifier\" not found"

As I don't have the time or knowledge for writing custom serialisers or similar, I have been using a semi-satisfactory work-around of

g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId)).Values<string>().Next();

This adds the edge just fine, although I have nothing returned to prove it (can't work out how to return the id)

However, I have been asked to convert all my code to use Promises (as defined in ITraversal).  This has worked just fine with Vertex-based traversals, but I'm back to square one with Edges in that no matter what I try I get that damn exception again.

Here's a little of my (admittedly flakey) code:

var graphTrav = g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId));

// attempt 1
var result = await graphTrav.Promise<ITraversal>(traverse);

Func<ITraversal<Vertex, Edge>, ITraversal> traverse =
(trav) =>
{
    return trav.Iterate();
};

I cannot use values() on an itraversal object so trying iterate() to try and avoid a return object(?). Still get the exception


// attempt 2
var result = await graphTrav.Promise<string>(traverse);

Func<ITraversal<Vertex, Edge>, string> traverse =
(trav) =>
{
    GraphTraversal<Vertex, Edge> gt = (GraphTraversal<Vertex, Edge>)trav;
    return gt.Values<string>().Next();
};

here I've tried creating a GraphTraversal out of the Itraversal object. Janus stores the edge, but gives the exception even though it is meant to return a string like my work-around

I guess this may be more of a C# query than a gremlin(.net) one, but I would appreciate any help please.



shapesh...@...
 

Hi Florian

Thanks so much for your reply and the code you provided.  I had to upgrade from gremlin.net 3.2.7 to 3.3.1 to use it. Previously I'd got strange errors with anything more recent on even the simplest traversals, but all is good now, including returning edges at last.

One slight problem though.  This is the result I got from adding an edge:

edgeResult {e[][40976616-test->163868848]} Gremlin.Net.Structure.Edge
Id {JanusGraph.Net.Extensions.RelationIdentifier} object {JanusGraph.Net.Extensions.RelationIdentifier}
RelationId null string
+ InV {v[163868848]} Gremlin.Net.Structure.Vertex
Label "test" string
+ OutV {v[40976616]} Gremlin.Net.Structure.Vertex

As you can see, there is no id.

From the console I can see: e[oe1p9-oe9rc-8ufp-2pka0g][40976616-test->163868848]

To be clear, I'm connecting to the standard Janus 0.2


On Wednesday, 27 June 2018 19:09:40 UTC+1, Florian Hockmann wrote:
You say that you want to return the edge id to prove that it was actually created. Before talking about how you can fix this problem I just want to mention that you don't really need to prove that as you would get an exception if something went wrong. So, when you don't get an exception then the edge was created.

If you nevertheless want to return the edge id then you currently don't have any other option than implementing an edge id deserializer. I recently implemented a library for JanusGraph which extends Gremlin.Net and handles the serialization and deserialization of JanusGraph specific types (and also JanusGraph's search predicates) for you. This library is currently in review and should be added to JanusGraph itself but that will take some time. Until then, you can simply use the code from that pull request in your own project. Here are the relevant classes:

RelationIdentifierSerializer (only needed when you also want to search edges by their id)

Then you can use those classes to configure the serialization when you create the GremlinClient like this:

var reader = new GraphSON2Reader(new Dictionary<string, IGraphSONDeserializer>
   
{
       
{"janusgraph:RelationIdentifier", new RelationIdentifierDeserializer()}
   
});

var writer = new GraphSON2Writer(new Dictionary<Type, IGraphSONSerializer>
   
{
       
{typeof(RelationIdentifier), new RelationIdentifierSerializer()}
   
});

var client = new GremlinClient(_server, reader, writer, GremlinClient.GraphSON2MimeType);

(Note, the GraphSON2 specific aspects are only necessary when you use Gremlin.Net in a version of 3.3.0 or higher as Gremlin.Net then uses GraphSON3 by default which isn't supported by JanusGraph 0.2.0.)

BTW: You can also express the way you use the Promise step a bit easier like this:
var id = await g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId)).Id().Promise(t => t.Next());

Am Mittwoch, 27. Juni 2018 18:26:09 UTC+2 schrieb Richard Moss:
Apologies for not posting this in the user's group where I guess is where it should have gone.

Anyway, I've part-fixed my own problem by changing the initial traversal to:

g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId)).Values<string>();

which meant the following change:

Func<ITraversal<Vertex, String>, string> traverse =
                (trav) =>
                {
                    return trav.Next();
                };

Still can't return the id of the new edge though. Can't just return .id() as the resulting I/graphtraversal would be <vertex, object> and anything bar <vertex. string> causes the exception.


On Wednesday, 27 June 2018 15:32:35 UTC+1, Richard Moss wrote:
I found out a while ago that returning edges from Janus is a problem with gremlin.net as you get this exception:

"Deserializer for \"janusgraph:RelationIdentifier\" not found"

As I don't have the time or knowledge for writing custom serialisers or similar, I have been using a semi-satisfactory work-around of

g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId)).Values<string>().Next();

This adds the edge just fine, although I have nothing returned to prove it (can't work out how to return the id)

However, I have been asked to convert all my code to use Promises (as defined in ITraversal).  This has worked just fine with Vertex-based traversals, but I'm back to square one with Edges in that no matter what I try I get that damn exception again.

Here's a little of my (admittedly flakey) code:

var graphTrav = g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId));

// attempt 1
var result = await graphTrav.Promise<ITraversal>(traverse);

Func<ITraversal<Vertex, Edge>, ITraversal> traverse =
(trav) =>
{
    return trav.Iterate();
};

I cannot use values() on an itraversal object so trying iterate() to try and avoid a return object(?). Still get the exception


// attempt 2
var result = await graphTrav.Promise<string>(traverse);

Func<ITraversal<Vertex, Edge>, string> traverse =
(trav) =>
{
    GraphTraversal<Vertex, Edge> gt = (GraphTraversal<Vertex, Edge>)trav;
    return gt.Values<string>().Next();
};

here I've tried creating a GraphTraversal out of the Itraversal object. Janus stores the edge, but gives the exception even though it is meant to return a string like my work-around

I guess this may be more of a C# query than a gremlin(.net) one, but I would appreciate any help please.



Florian Hockmann <f...@...>
 

What exactly was the traversal you used to get that result?

Am Donnerstag, 28. Juni 2018 16:40:09 UTC+2 schrieb Richard Moss:

Hi Florian

Thanks so much for your reply and the code you provided.  I had to upgrade from gremlin.net 3.2.7 to 3.3.1 to use it. Previously I'd got strange errors with anything more recent on even the simplest traversals, but all is good now, including returning edges at last.

One slight problem though.  This is the result I got from adding an edge:

edgeResult {e[][40976616-test->163868848]} Gremlin.Net.Structure.Edge
Id {JanusGraph.Net.Extensions.RelationIdentifier} object {JanusGraph.Net.Extensions.RelationIdentifier}
RelationId null string
+ InV {v[163868848]} Gremlin.Net.Structure.Vertex
Label "test" string
+ OutV {v[40976616]} Gremlin.Net.Structure.Vertex

As you can see, there is no id.

From the console I can see: e[oe1p9-oe9rc-8ufp-2pka0g][40976616-test->163868848]

To be clear, I'm connecting to the standard Janus 0.2


On Wednesday, 27 June 2018 19:09:40 UTC+1, Florian Hockmann wrote:
You say that you want to return the edge id to prove that it was actually created. Before talking about how you can fix this problem I just want to mention that you don't really need to prove that as you would get an exception if something went wrong. So, when you don't get an exception then the edge was created.

If you nevertheless want to return the edge id then you currently don't have any other option than implementing an edge id deserializer. I recently implemented a library for JanusGraph which extends Gremlin.Net and handles the serialization and deserialization of JanusGraph specific types (and also JanusGraph's search predicates) for you. This library is currently in review and should be added to JanusGraph itself but that will take some time. Until then, you can simply use the code from that pull request in your own project. Here are the relevant classes:

RelationIdentifierSerializer (only needed when you also want to search edges by their id)

Then you can use those classes to configure the serialization when you create the GremlinClient like this:

var reader = new GraphSON2Reader(new Dictionary<string, IGraphSONDeserializer>
   
{
       
{"janusgraph:RelationIdentifier", new RelationIdentifierDeserializer()}
   
});

var writer = new GraphSON2Writer(new Dictionary<Type, IGraphSONSerializer>
   
{
       
{typeof(RelationIdentifier), new RelationIdentifierSerializer()}
   
});

var client = new GremlinClient(_server, reader, writer, GremlinClient.GraphSON2MimeType);

(Note, the GraphSON2 specific aspects are only necessary when you use Gremlin.Net in a version of 3.3.0 or higher as Gremlin.Net then uses GraphSON3 by default which isn't supported by JanusGraph 0.2.0.)

BTW: You can also express the way you use the Promise step a bit easier like this:
var id = await g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId)).Id().Promise(t => t.Next());

Am Mittwoch, 27. Juni 2018 18:26:09 UTC+2 schrieb Richard Moss:
Apologies for not posting this in the user's group where I guess is where it should have gone.

Anyway, I've part-fixed my own problem by changing the initial traversal to:

g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId)).Values<string>();

which meant the following change:

Func<ITraversal<Vertex, String>, string> traverse =
                (trav) =>
                {
                    return trav.Next();
                };

Still can't return the id of the new edge though. Can't just return .id() as the resulting I/graphtraversal would be <vertex, object> and anything bar <vertex. string> causes the exception.


On Wednesday, 27 June 2018 15:32:35 UTC+1, Richard Moss wrote:
I found out a while ago that returning edges from Janus is a problem with gremlin.net as you get this exception:

"Deserializer for \"janusgraph:RelationIdentifier\" not found"

As I don't have the time or knowledge for writing custom serialisers or similar, I have been using a semi-satisfactory work-around of

g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId)).Values<string>().Next();

This adds the edge just fine, although I have nothing returned to prove it (can't work out how to return the id)

However, I have been asked to convert all my code to use Promises (as defined in ITraversal).  This has worked just fine with Vertex-based traversals, but I'm back to square one with Edges in that no matter what I try I get that damn exception again.

Here's a little of my (admittedly flakey) code:

var graphTrav = g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId));

// attempt 1
var result = await graphTrav.Promise<ITraversal>(traverse);

Func<ITraversal<Vertex, Edge>, ITraversal> traverse =
(trav) =>
{
    return trav.Iterate();
};

I cannot use values() on an itraversal object so trying iterate() to try and avoid a return object(?). Still get the exception


// attempt 2
var result = await graphTrav.Promise<string>(traverse);

Func<ITraversal<Vertex, Edge>, string> traverse =
(trav) =>
{
    GraphTraversal<Vertex, Edge> gt = (GraphTraversal<Vertex, Edge>)trav;
    return gt.Values<string>().Next();
};

here I've tried creating a GraphTraversal out of the Itraversal object. Janus stores the edge, but gives the exception even though it is meant to return a string like my work-around

I guess this may be more of a C# query than a gremlin(.net) one, but I would appreciate any help please.



shapesh...@...
 

I can't work out how to see the traversal as sent to Janus, but I write it in code simply as:
var graphTrav = g.V(edgeTemplate.FromVertexId).AddE(edgeTemplate.Label).To(g.V(edgeTemplate.ToVertexId));
...
var edgeResult = await graphTrav.Promise(t => t.Next());

This is from the logs (which I can't see directly, only via what is logged in our Kibana server)

RequestMessage{, requestId=8cdf02b4-546f-45ed-8ad6-fb677d94ff7e, op='bytecode', processor='traversal', args={gremlin=[[], [V(122884096), addE(test), to([[], [V(81924328)]])]], aliases={g=dev}}}


On Friday, 29 June 2018 20:48:26 UTC+1, Florian Hockmann wrote:
What exactly was the traversal you used to get that result?

Am Donnerstag, 28. Juni 2018 16:40:09 UTC+2 schrieb Richard Moss:
Hi Florian

Thanks so much for your reply and the code you provided.  I had to upgrade from gremlin.net 3.2.7 to 3.3.1 to use it. Previously I'd got strange errors with anything more recent on even the simplest traversals, but all is good now, including returning edges at last.

One slight problem though.  This is the result I got from adding an edge:

edgeResult {e[][40976616-test->163868848]} Gremlin.Net.Structure.Edge
Id {JanusGraph.Net.Extensions.RelationIdentifier} object {JanusGraph.Net.Extensions.RelationIdentifier}
RelationId null string
+ InV {v[163868848]} Gremlin.Net.Structure.Vertex
Label "test" string
+ OutV {v[40976616]} Gremlin.Net.Structure.Vertex

As you can see, there is no id.

From the console I can see: e[oe1p9-oe9rc-8ufp-2pka0g][40976616-test->163868848]

To be clear, I'm connecting to the standard Janus 0.2


On Wednesday, 27 June 2018 19:09:40 UTC+1, Florian Hockmann wrote:
You say that you want to return the edge id to prove that it was actually created. Before talking about how you can fix this problem I just want to mention that you don't really need to prove that as you would get an exception if something went wrong. So, when you don't get an exception then the edge was created.

If you nevertheless want to return the edge id then you currently don't have any other option than implementing an edge id deserializer. I recently implemented a library for JanusGraph which extends Gremlin.Net and handles the serialization and deserialization of JanusGraph specific types (and also JanusGraph's search predicates) for you. This library is currently in review and should be added to JanusGraph itself but that will take some time. Until then, you can simply use the code from that pull request in your own project. Here are the relevant classes:

RelationIdentifierSerializer (only needed when you also want to search edges by their id)

Then you can use those classes to configure the serialization when you create the GremlinClient like this:

var reader = new GraphSON2Reader(new Dictionary<string, IGraphSONDeserializer>
   
{
       
{"janusgraph:RelationIdentifier", new RelationIdentifierDeserializer()}
   
});

var writer = new GraphSON2Writer(new Dictionary<Type, IGraphSONSerializer>
   
{
       
{typeof(RelationIdentifier), new RelationIdentifierSerializer()}
   
});

var client = new GremlinClient(_server, reader, writer, GremlinClient.GraphSON2MimeType);

(Note, the GraphSON2 specific aspects are only necessary when you use Gremlin.Net in a version of 3.3.0 or higher as Gremlin.Net then uses GraphSON3 by default which isn't supported by JanusGraph 0.2.0.)

BTW: You can also express the way you use the Promise step a bit easier like this:
var id = await g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId)).Id().Promise(t => t.Next());

Am Mittwoch, 27. Juni 2018 18:26:09 UTC+2 schrieb Richard Moss:
Apologies for not posting this in the user's group where I guess is where it should have gone.

Anyway, I've part-fixed my own problem by changing the initial traversal to:

g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId)).Values<string>();

which meant the following change:

Func<ITraversal<Vertex, String>, string> traverse =
                (trav) =>
                {
                    return trav.Next();
                };

Still can't return the id of the new edge though. Can't just return .id() as the resulting I/graphtraversal would be <vertex, object> and anything bar <vertex. string> causes the exception.


On Wednesday, 27 June 2018 15:32:35 UTC+1, Richard Moss wrote:
I found out a while ago that returning edges from Janus is a problem with gremlin.net as you get this exception:

"Deserializer for \"janusgraph:RelationIdentifier\" not found"

As I don't have the time or knowledge for writing custom serialisers or similar, I have been using a semi-satisfactory work-around of

g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId)).Values<string>().Next();

This adds the edge just fine, although I have nothing returned to prove it (can't work out how to return the id)

However, I have been asked to convert all my code to use Promises (as defined in ITraversal).  This has worked just fine with Vertex-based traversals, but I'm back to square one with Edges in that no matter what I try I get that damn exception again.

Here's a little of my (admittedly flakey) code:

var graphTrav = g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId));

// attempt 1
var result = await graphTrav.Promise<ITraversal>(traverse);

Func<ITraversal<Vertex, Edge>, ITraversal> traverse =
(trav) =>
{
    return trav.Iterate();
};

I cannot use values() on an itraversal object so trying iterate() to try and avoid a return object(?). Still get the exception


// attempt 2
var result = await graphTrav.Promise<string>(traverse);

Func<ITraversal<Vertex, Edge>, string> traverse =
(trav) =>
{
    GraphTraversal<Vertex, Edge> gt = (GraphTraversal<Vertex, Edge>)trav;
    return gt.Values<string>().Next();
};

here I've tried creating a GraphTraversal out of the Itraversal object. Janus stores the edge, but gives the exception even though it is meant to return a string like my work-around

I guess this may be more of a C# query than a gremlin(.net) one, but I would appreciate any help please.



Florian Hockmann <f...@...>
 

I just tried to reproduce your problem but it worked for me as expected. Here is the test I used for that:

var g = new Graph().Traversal().WithRemote(_connectionFactory.CreateRemoteConnection());
var fromVertexId = g.V().Has("name", "hercules").Id().Next();
var toVertexId = g.V().Has("name", "pluto").Id().Next();

var edge = await g.V(fromVertexId).AddE("brother").To(g.V(toVertexId)).Promise(t => t.Next());

Assert.NotNull(edge.Id);
Assert.IsType<RelationIdentifier>(edge.Id);


I used the Graph of the Gods and the tests ran through without any problems. The value of edge.Id was 3yu-3ao-b2t-6cw. The _connectionFactory is the one from the linked pull request but it basically just creates a connection configured with the linked GraphSON serializers.

So in order to help you with your problem, it would be good to have a minimal self contained example that shows your problem.

Am Montag, 2. Juli 2018 11:03:47 UTC+2 schrieb Richard Moss:

I can't work out how to see the traversal as sent to Janus, but I write it in code simply as:
var graphTrav = g.V(edgeTemplate.FromVertexId).AddE(edgeTemplate.Label).To(g.V(edgeTemplate.ToVertexId));
...
var edgeResult = await graphTrav.Promise(t => t.Next());

This is from the logs (which I can't see directly, only via what is logged in our Kibana server)

RequestMessage{, requestId=8cdf02b4-546f-45ed-8ad6-fb677d94ff7e, op='bytecode', processor='traversal', args={gremlin=[[], [V(122884096), addE(test), to([[], [V(81924328)]])]], aliases={g=dev}}}


On Friday, 29 June 2018 20:48:26 UTC+1, Florian Hockmann wrote:
What exactly was the traversal you used to get that result?

Am Donnerstag, 28. Juni 2018 16:40:09 UTC+2 schrieb Richard Moss:
Hi Florian

Thanks so much for your reply and the code you provided.  I had to upgrade from gremlin.net 3.2.7 to 3.3.1 to use it. Previously I'd got strange errors with anything more recent on even the simplest traversals, but all is good now, including returning edges at last.

One slight problem though.  This is the result I got from adding an edge:

edgeResult {e[][40976616-test->163868848]} Gremlin.Net.Structure.Edge
Id {JanusGraph.Net.Extensions.RelationIdentifier} object {JanusGraph.Net.Extensions.RelationIdentifier}
RelationId null string
+ InV {v[163868848]} Gremlin.Net.Structure.Vertex
Label "test" string
+ OutV {v[40976616]} Gremlin.Net.Structure.Vertex

As you can see, there is no id.

From the console I can see: e[oe1p9-oe9rc-8ufp-2pka0g][40976616-test->163868848]

To be clear, I'm connecting to the standard Janus 0.2


On Wednesday, 27 June 2018 19:09:40 UTC+1, Florian Hockmann wrote:
You say that you want to return the edge id to prove that it was actually created. Before talking about how you can fix this problem I just want to mention that you don't really need to prove that as you would get an exception if something went wrong. So, when you don't get an exception then the edge was created.

If you nevertheless want to return the edge id then you currently don't have any other option than implementing an edge id deserializer. I recently implemented a library for JanusGraph which extends Gremlin.Net and handles the serialization and deserialization of JanusGraph specific types (and also JanusGraph's search predicates) for you. This library is currently in review and should be added to JanusGraph itself but that will take some time. Until then, you can simply use the code from that pull request in your own project. Here are the relevant classes:

RelationIdentifierSerializer (only needed when you also want to search edges by their id)

Then you can use those classes to configure the serialization when you create the GremlinClient like this:

var reader = new GraphSON2Reader(new Dictionary<string, IGraphSONDeserializer>
   
{
       
{"janusgraph:RelationIdentifier", new RelationIdentifierDeserializer()}
   
});

var writer = new GraphSON2Writer(new Dictionary<Type, IGraphSONSerializer>
   
{
       
{typeof(RelationIdentifier), new RelationIdentifierSerializer()}
   
});

var client = new GremlinClient(_server, reader, writer, GremlinClient.GraphSON2MimeType);

(Note, the GraphSON2 specific aspects are only necessary when you use Gremlin.Net in a version of 3.3.0 or higher as Gremlin.Net then uses GraphSON3 by default which isn't supported by JanusGraph 0.2.0.)

BTW: You can also express the way you use the Promise step a bit easier like this:
var id = await g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId)).Id().Promise(t => t.Next());

Am Mittwoch, 27. Juni 2018 18:26:09 UTC+2 schrieb Richard Moss:
Apologies for not posting this in the user's group where I guess is where it should have gone.

Anyway, I've part-fixed my own problem by changing the initial traversal to:

g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId)).Values<string>();

which meant the following change:

Func<ITraversal<Vertex, String>, string> traverse =
                (trav) =>
                {
                    return trav.Next();
                };

Still can't return the id of the new edge though. Can't just return .id() as the resulting I/graphtraversal would be <vertex, object> and anything bar <vertex. string> causes the exception.


On Wednesday, 27 June 2018 15:32:35 UTC+1, Richard Moss wrote:
I found out a while ago that returning edges from Janus is a problem with gremlin.net as you get this exception:

"Deserializer for \"janusgraph:RelationIdentifier\" not found"

As I don't have the time or knowledge for writing custom serialisers or similar, I have been using a semi-satisfactory work-around of

g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId)).Values<string>().Next();

This adds the edge just fine, although I have nothing returned to prove it (can't work out how to return the id)

However, I have been asked to convert all my code to use Promises (as defined in ITraversal).  This has worked just fine with Vertex-based traversals, but I'm back to square one with Edges in that no matter what I try I get that damn exception again.

Here's a little of my (admittedly flakey) code:

var graphTrav = g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId));

// attempt 1
var result = await graphTrav.Promise<ITraversal>(traverse);

Func<ITraversal<Vertex, Edge>, ITraversal> traverse =
(trav) =>
{
    return trav.Iterate();
};

I cannot use values() on an itraversal object so trying iterate() to try and avoid a return object(?). Still get the exception


// attempt 2
var result = await graphTrav.Promise<string>(traverse);

Func<ITraversal<Vertex, Edge>, string> traverse =
(trav) =>
{
    GraphTraversal<Vertex, Edge> gt = (GraphTraversal<Vertex, Edge>)trav;
    return gt.Values<string>().Next();
};

here I've tried creating a GraphTraversal out of the Itraversal object. Janus stores the edge, but gives the exception even though it is meant to return a string like my work-around

I guess this may be more of a C# query than a gremlin(.net) one, but I would appreciate any help please.



shapesh...@...
 

Apologies for this late reply, Florian

It turns out I had taken your original response a bit literally and just grabbed the 3 files you linked to without checking for other new code. It seems to work now, but I can't say for sure it's the extra code as before I could add it I had to move to another janus installation.

I won't bore you with the details, but I have had weird problems lately where my graph is just not working properly. For example, I have a test that adds a node, but checking through the console it has not been added even though (sometimes) I may get a back a result with new vertex id! I have moved temporarily to a 0.3 build, but just today the same thing is happening again. Creating a new graph seems to be a (temporary) fix.

All I can think of as a cause is that I am frequently issuing g.V().drop commands between tests.  Could this be causing a problem behind the scenes with indexing or something?

On Tuesday, 3 July 2018 19:58:16 UTC+1, Florian Hockmann wrote:
I just tried to reproduce your problem but it worked for me as expected. Here is the test I used for that:

var g = new Graph().Traversal().WithRemote(_connectionFactory.CreateRemoteConnection());
var fromVertexId = g.V().Has("name", "hercules").Id().Next();
var toVertexId = g.V().Has("name", "pluto").Id().Next();

var edge = await g.V(fromVertexId).AddE("brother").To(g.V(toVertexId)).Promise(t => t.Next());

Assert.NotNull(edge.Id);
Assert.IsType<RelationIdentifier>(edge.Id);


I used the Graph of the Gods and the tests ran through without any problems. The value of edge.Id was 3yu-3ao-b2t-6cw. The _connectionFactory is the one from the linked pull request but it basically just creates a connection configured with the linked GraphSON serializers.

So in order to help you with your problem, it would be good to have a minimal self contained example that shows your problem.

Am Montag, 2. Juli 2018 11:03:47 UTC+2 schrieb Richard Moss:
I can't work out how to see the traversal as sent to Janus, but I write it in code simply as:
var graphTrav = g.V(edgeTemplate.FromVertexId).AddE(edgeTemplate.Label).To(g.V(edgeTemplate.ToVertexId));
...
var edgeResult = await graphTrav.Promise(t => t.Next());

This is from the logs (which I can't see directly, only via what is logged in our Kibana server)

RequestMessage{, requestId=8cdf02b4-546f-45ed-8ad6-fb677d94ff7e, op='bytecode', processor='traversal', args={gremlin=[[], [V(122884096), addE(test), to([[], [V(81924328)]])]], aliases={g=dev}}}


On Friday, 29 June 2018 20:48:26 UTC+1, Florian Hockmann wrote:
What exactly was the traversal you used to get that result?

Am Donnerstag, 28. Juni 2018 16:40:09 UTC+2 schrieb Richard Moss:
Hi Florian

Thanks so much for your reply and the code you provided.  I had to upgrade from gremlin.net 3.2.7 to 3.3.1 to use it. Previously I'd got strange errors with anything more recent on even the simplest traversals, but all is good now, including returning edges at last.

One slight problem though.  This is the result I got from adding an edge:

edgeResult {e[][40976616-test->163868848]} Gremlin.Net.Structure.Edge
Id {JanusGraph.Net.Extensions.RelationIdentifier} object {JanusGraph.Net.Extensions.RelationIdentifier}
RelationId null string
+ InV {v[163868848]} Gremlin.Net.Structure.Vertex
Label "test" string
+ OutV {v[40976616]} Gremlin.Net.Structure.Vertex

As you can see, there is no id.

From the console I can see: e[oe1p9-oe9rc-8ufp-2pka0g][40976616-test->163868848]

To be clear, I'm connecting to the standard Janus 0.2


On Wednesday, 27 June 2018 19:09:40 UTC+1, Florian Hockmann wrote:
You say that you want to return the edge id to prove that it was actually created. Before talking about how you can fix this problem I just want to mention that you don't really need to prove that as you would get an exception if something went wrong. So, when you don't get an exception then the edge was created.

If you nevertheless want to return the edge id then you currently don't have any other option than implementing an edge id deserializer. I recently implemented a library for JanusGraph which extends Gremlin.Net and handles the serialization and deserialization of JanusGraph specific types (and also JanusGraph's search predicates) for you. This library is currently in review and should be added to JanusGraph itself but that will take some time. Until then, you can simply use the code from that pull request in your own project. Here are the relevant classes:

RelationIdentifierSerializer (only needed when you also want to search edges by their id)

Then you can use those classes to configure the serialization when you create the GremlinClient like this:

var reader = new GraphSON2Reader(new Dictionary<string, IGraphSONDeserializer>
   
{
       
{"janusgraph:RelationIdentifier", new RelationIdentifierDeserializer()}
   
});

var writer = new GraphSON2Writer(new Dictionary<Type, IGraphSONSerializer>
   
{
       
{typeof(RelationIdentifier), new RelationIdentifierSerializer()}
   
});

var client = new GremlinClient(_server, reader, writer, GremlinClient.GraphSON2MimeType);

(Note, the GraphSON2 specific aspects are only necessary when you use Gremlin.Net in a version of 3.3.0 or higher as Gremlin.Net then uses GraphSON3 by default which isn't supported by JanusGraph 0.2.0.)

BTW: You can also express the way you use the Promise step a bit easier like this:
var id = await g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId)).Id().Promise(t => t.Next());

Am Mittwoch, 27. Juni 2018 18:26:09 UTC+2 schrieb Richard Moss:
Apologies for not posting this in the user's group where I guess is where it should have gone.

Anyway, I've part-fixed my own problem by changing the initial traversal to:

g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId)).Values<string>();

which meant the following change:

Func<ITraversal<Vertex, String>, string> traverse =
                (trav) =>
                {
                    return trav.Next();
                };

Still can't return the id of the new edge though. Can't just return .id() as the resulting I/graphtraversal would be <vertex, object> and anything bar <vertex. string> causes the exception.


On Wednesday, 27 June 2018 15:32:35 UTC+1, Richard Moss wrote:
I found out a while ago that returning edges from Janus is a problem with gremlin.net as you get this exception:

"Deserializer for \"janusgraph:RelationIdentifier\" not found"

As I don't have the time or knowledge for writing custom serialisers or similar, I have been using a semi-satisfactory work-around of

g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId)).Values<string>().Next();

This adds the edge just fine, although I have nothing returned to prove it (can't work out how to return the id)

However, I have been asked to convert all my code to use Promises (as defined in ITraversal).  This has worked just fine with Vertex-based traversals, but I'm back to square one with Edges in that no matter what I try I get that damn exception again.

Here's a little of my (admittedly flakey) code:

var graphTrav = g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId));

// attempt 1
var result = await graphTrav.Promise<ITraversal>(traverse);

Func<ITraversal<Vertex, Edge>, ITraversal> traverse =
(trav) =>
{
    return trav.Iterate();
};

I cannot use values() on an itraversal object so trying iterate() to try and avoid a return object(?). Still get the exception


// attempt 2
var result = await graphTrav.Promise<string>(traverse);

Func<ITraversal<Vertex, Edge>, string> traverse =
(trav) =>
{
    GraphTraversal<Vertex, Edge> gt = (GraphTraversal<Vertex, Edge>)trav;
    return gt.Values<string>().Next();
};

here I've tried creating a GraphTraversal out of the Itraversal object. Janus stores the edge, but gives the exception even though it is meant to return a string like my work-around

I guess this may be more of a C# query than a gremlin(.net) one, but I would appreciate any help please.



Florian Hockmann <f...@...>
 

I am frequently issuing g.V().drop commands between tests.  Could this be causing a problem behind the scenes with indexing or something?
It's hard to help you without knowing what exactly you do in those tests. You mention that your tests add vertices and that you check whether these vertices were actually added via the Console but when do you execute g.V().drop()? When you do that in parallen then it of course leads to problems.

The traversal you are using with Gremlin.Net to add a vertex should either work every time or not at all in case you did something wrong. But as long as you cannot reduce your problem to a minimal code sample that reproduces your problem, it's really hard to provide any help.

Am Freitag, 13. Juli 2018 17:43:17 UTC+2 schrieb Richard Moss:
Apologies for this late reply, Florian

It turns out I had taken your original response a bit literally and just grabbed the 3 files you linked to without checking for other new code. It seems to work now, but I can't say for sure it's the extra code as before I could add it I had to move to another janus installation.

I won't bore you with the details, but I have had weird problems lately where my graph is just not working properly. For example, I have a test that adds a node, but checking through the console it has not been added even though (sometimes) I may get a back a result with new vertex id! I have moved temporarily to a 0.3 build, but just today the same thing is happening again. Creating a new graph seems to be a (temporary) fix.

All I can think of as a cause is that I am frequently issuing g.V().drop commands between tests.  Could this be causing a problem behind the scenes with indexing or something?

On Tuesday, 3 July 2018 19:58:16 UTC+1, Florian Hockmann wrote:
I just tried to reproduce your problem but it worked for me as expected. Here is the test I used for that:

var g = new Graph().Traversal().WithRemote(_connectionFactory.CreateRemoteConnection());
var fromVertexId = g.V().Has("name", "hercules").Id().Next();
var toVertexId = g.V().Has("name", "pluto").Id().Next();

var edge = await g.V(fromVertexId).AddE("brother").To(g.V(toVertexId)).Promise(t => t.Next());

Assert.NotNull(edge.Id);
Assert.IsType<RelationIdentifier>(edge.Id);


I used the Graph of the Gods and the tests ran through without any problems. The value of edge.Id was 3yu-3ao-b2t-6cw. The _connectionFactory is the one from the linked pull request but it basically just creates a connection configured with the linked GraphSON serializers.

So in order to help you with your problem, it would be good to have a minimal self contained example that shows your problem.

Am Montag, 2. Juli 2018 11:03:47 UTC+2 schrieb Richard Moss:
I can't work out how to see the traversal as sent to Janus, but I write it in code simply as:
var graphTrav = g.V(edgeTemplate.FromVertexId).AddE(edgeTemplate.Label).To(g.V(edgeTemplate.ToVertexId));
...
var edgeResult = await graphTrav.Promise(t => t.Next());

This is from the logs (which I can't see directly, only via what is logged in our Kibana server)

RequestMessage{, requestId=8cdf02b4-546f-45ed-8ad6-fb677d94ff7e, op='bytecode', processor='traversal', args={gremlin=[[], [V(122884096), addE(test), to([[], [V(81924328)]])]], aliases={g=dev}}}


On Friday, 29 June 2018 20:48:26 UTC+1, Florian Hockmann wrote:
What exactly was the traversal you used to get that result?

Am Donnerstag, 28. Juni 2018 16:40:09 UTC+2 schrieb Richard Moss:
Hi Florian

Thanks so much for your reply and the code you provided.  I had to upgrade from gremlin.net 3.2.7 to 3.3.1 to use it. Previously I'd got strange errors with anything more recent on even the simplest traversals, but all is good now, including returning edges at last.

One slight problem though.  This is the result I got from adding an edge:

edgeResult {e[][40976616-test->163868848]} Gremlin.Net.Structure.Edge
Id {JanusGraph.Net.Extensions.RelationIdentifier} object {JanusGraph.Net.Extensions.RelationIdentifier}
RelationId null string
+ InV {v[163868848]} Gremlin.Net.Structure.Vertex
Label "test" string
+ OutV {v[40976616]} Gremlin.Net.Structure.Vertex

As you can see, there is no id.

From the console I can see: e[oe1p9-oe9rc-8ufp-2pka0g][40976616-test->163868848]

To be clear, I'm connecting to the standard Janus 0.2


On Wednesday, 27 June 2018 19:09:40 UTC+1, Florian Hockmann wrote:
You say that you want to return the edge id to prove that it was actually created. Before talking about how you can fix this problem I just want to mention that you don't really need to prove that as you would get an exception if something went wrong. So, when you don't get an exception then the edge was created.

If you nevertheless want to return the edge id then you currently don't have any other option than implementing an edge id deserializer. I recently implemented a library for JanusGraph which extends Gremlin.Net and handles the serialization and deserialization of JanusGraph specific types (and also JanusGraph's search predicates) for you. This library is currently in review and should be added to JanusGraph itself but that will take some time. Until then, you can simply use the code from that pull request in your own project. Here are the relevant classes:

RelationIdentifierSerializer (only needed when you also want to search edges by their id)

Then you can use those classes to configure the serialization when you create the GremlinClient like this:

var reader = new GraphSON2Reader(new Dictionary<string, IGraphSONDeserializer>
   
{
       
{"janusgraph:RelationIdentifier", new RelationIdentifierDeserializer()}
   
});

var writer = new GraphSON2Writer(new Dictionary<Type, IGraphSONSerializer>
   
{
       
{typeof(RelationIdentifier), new RelationIdentifierSerializer()}
   
});

var client = new GremlinClient(_server, reader, writer, GremlinClient.GraphSON2MimeType);

(Note, the GraphSON2 specific aspects are only necessary when you use Gremlin.Net in a version of 3.3.0 or higher as Gremlin.Net then uses GraphSON3 by default which isn't supported by JanusGraph 0.2.0.)

BTW: You can also express the way you use the Promise step a bit easier like this:
var id = await g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId)).Id().Promise(t => t.Next());

Am Mittwoch, 27. Juni 2018 18:26:09 UTC+2 schrieb Richard Moss:
Apologies for not posting this in the user's group where I guess is where it should have gone.

Anyway, I've part-fixed my own problem by changing the initial traversal to:

g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId)).Values<string>();

which meant the following change:

Func<ITraversal<Vertex, String>, string> traverse =
                (trav) =>
                {
                    return trav.Next();
                };

Still can't return the id of the new edge though. Can't just return .id() as the resulting I/graphtraversal would be <vertex, object> and anything bar <vertex. string> causes the exception.


On Wednesday, 27 June 2018 15:32:35 UTC+1, Richard Moss wrote:
I found out a while ago that returning edges from Janus is a problem with gremlin.net as you get this exception:

"Deserializer for \"janusgraph:RelationIdentifier\" not found"

As I don't have the time or knowledge for writing custom serialisers or similar, I have been using a semi-satisfactory work-around of

g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId)).Values<string>().Next();

This adds the edge just fine, although I have nothing returned to prove it (can't work out how to return the id)

However, I have been asked to convert all my code to use Promises (as defined in ITraversal).  This has worked just fine with Vertex-based traversals, but I'm back to square one with Edges in that no matter what I try I get that damn exception again.

Here's a little of my (admittedly flakey) code:

var graphTrav = g.V(edge.FromVertexId).AddE(edge.Label).To(g.V(edge.ToVertexId));

// attempt 1
var result = await graphTrav.Promise<ITraversal>(traverse);

Func<ITraversal<Vertex, Edge>, ITraversal> traverse =
(trav) =>
{
    return trav.Iterate();
};

I cannot use values() on an itraversal object so trying iterate() to try and avoid a return object(?). Still get the exception


// attempt 2
var result = await graphTrav.Promise<string>(traverse);

Func<ITraversal<Vertex, Edge>, string> traverse =
(trav) =>
{
    GraphTraversal<Vertex, Edge> gt = (GraphTraversal<Vertex, Edge>)trav;
    return gt.Values<string>().Next();
};

here I've tried creating a GraphTraversal out of the Itraversal object. Janus stores the edge, but gives the exception even though it is meant to return a string like my work-around

I guess this may be more of a C# query than a gremlin(.net) one, but I would appreciate any help please.