SteelBridgeLabs / neo4j-gremlin-bolt

Apache License 2.0
0 stars 1 forks source link

Uncoercible exception on gremlin graph traversal #63

Closed MohsenIT closed 6 years ago

MohsenIT commented 6 years ago

I try to connect gremlin to neo4j 3.2.3 and 3.2.5 with this code:

Driver driver = GraphDatabase.driver("bolt://localhost", AuthTokens.basic("neo4j", "pass"));
Neo4JElementIdProvider<?> vertexIdProvider = new DatabaseSequenceElementIdProvider(driver);
Neo4JElementIdProvider<?> edgeIdProvider = new DatabaseSequenceElementIdProvider(driver);

Neo4JGraph graph = new Neo4JGraph(driver, vertexIdProvider, edgeIdProvider);
graph.setProfilerEnabled(true);
int cnt = graph.execute("MATCH (n) RETURN count(n)").next().get(0).asInt();
List records = graph.execute("MATCH (n1) WHERE n1.resolved_id = \"31586\" RETURN n1").list();
// result: a list with 10 element

GraphTraversalSource g = graph.traversal();
List<Vertex> s = g.V().has("resolved_id", "31586").toList();
// result: org.neo4j.driver.v1.exceptions.value.Uncoercible: Cannot coerce NULL to Java long

As I commented when we use graph traversal none of queries work Uncoercible exception. it seems that the traversal function return null to this query {g.V().has("resolved_id", "31586")}. this query is true because when I use embedded connection to this database, it results correctly. What is the problem?

attachment: this is my pom.xml dependencies:

<dependency>
    <groupId>org.apache.tinkerpop</groupId>
    <artifactId>gremlin-core</artifactId>
    <version>3.2.5</version>
</dependency>
<dependency>
    <groupId>org.apache.tinkerpop</groupId>
    <artifactId>neo4j-gremlin</artifactId>
    <version>3.2.5</version>
</dependency>

<dependency>
    <groupId>com.steelbridgelabs.oss</groupId>
    <artifactId>neo4j-gremlin-bolt</artifactId>
    <version>0.2.25</version>
</dependency>
MohsenIT commented 6 years ago

Hi, When I change the Id providers it works correctly:

Neo4JElementIdProvider<?> vertexIdProvider = new Neo4JNativeElementIdProvider();
Neo4JElementIdProvider<?> edgeIdProvider = new Neo4JNativeElementIdProvider();

What is the problem of DatabaseSequenceElementIdProvider ?

rjbaucells commented 6 years ago

The two examples you mentioned should give you the same results with a big difference on how the query is executed:

List records = graph.execute("MATCH (n1) WHERE n1.resolved_id = \"31586\" RETURN n1").list();

Will execute the given statement against the database, fetch 10 vertices from the database and give those as a result.

GraphTraversalSource g = graph.traversal();
List<Vertex> s = g.V().has("resolved_id", "31586").toList();

Will execute the statement MATCH (n) RETURN n, fetch all vertices from the database and provide that information to the GraphTraversalSource instance that will be in charge of filtering out the un-wanted results.

I do not think there is a problem with the provider, what it is possible is that while fetching all nodes from the database (MATCH (n) RETURN n) the library is presented with a node without identifier. A quick way to find if this is the case would be executing something like the following statement in the neo4j browser console:

MATCH (n) WHERE n.id IS NULL RETURN n LIMIT 10
MohsenIT commented 6 years ago

Hi Rogelio, You are right. There are several nodes with null ids. Thanks a lot

cybe commented 5 years ago

Sorry for reusing this already closed issue, but I run into the same problem when using the DatabaseSequenceElementIdProvider. This happens on simple queries like g.V().hasLabel("Something"), because the node that stores the next ID (UniqueIdentifierGenerator) itself has no property id. Any idea how to approach this properly? I'm happy to provide more information.

rjbaucells commented 5 years ago

Just execute a CYPHER statement that creates the "id" property on all nodes, something like

MATCH (n) WHERE NOT EXISTS(n.id) SET n.id=ID(n)

Make sure it is ok to assign the node ID to the id field, it depends on your business logic

cybe commented 5 years ago

Just execute a CYPHER statement that creates the "id" property on all nodes

Thought about this but was not quite sure about any side effects within DatabaseSequenceElementIdProvider. Thank you!