cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

How to handle varying return type?

I'm running into something with a custom procedure that collects information from the graph before computing some values for new entities.

All of my data for nodes being queries were imported from CSV with values managed like this:
WITH row, CASE WHEN toInteger(row.milex)="-9" OR row.milex='' THEN "UNK" ELSE toInteger(row.milex) END AS myMilex,
...then saved to the node...
(f:Fact{value:myMilex})

When I call my procedure that takes values from the Fact node, I get conflicting results. If I assume that the Fact.value is a Long, I get an error that java.lang.Integer cannot be cast to java.lang.Long. If I assume that the Fact.value is an Integer, I get an error that java.lang.Long cannot be cast to java.lang.Integer.

Looking deeper, I find that the value in the database may indeed be sometimes stored as a long and sometimes as an integer, even though I specified that it should be an integer when I imported the data.

For example,
MATCH (t:Territory{mapKey:"United States of 1816"})--(p:Polity)-[m:MILEX{during:1816}]-(f:Fact) RETURN Type(f.value)
returns
Expected a Relationship, got: Long(3823)

whereas,
MATCH (t:Territory{mapKey:"Switzerland of 1816"})--(p:Polity)-[m:MILEX{during:1816}]-(f:Fact) RETURN Type(f.value)
returns
Expected a Relationship, got: Int(44)

I've found some workarounds, like using nested try/catch blocks or casting first to a String and then parsing it. int value = Integer.parseInt(r.getProperty("value").toString()) but both of those seem a bit hackish.

What should be happening?

1 ACCEPTED SOLUTION

You can use Number in your return type.

it should never be a string if you store numeric values.

and when accessing a property ((Number)r.getProperty("value")).longValue()

In general watch out when you store data from the Java API.
Cypher only know's Long, no Integer or such.

Fun that you use type(x) to report the type 🙂 because it's meant for rel-types.

View solution in original post

2 REPLIES 2

You can use Number in your return type.

it should never be a string if you store numeric values.

and when accessing a property ((Number)r.getProperty("value")).longValue()

In general watch out when you store data from the Java API.
Cypher only know's Long, no Integer or such.

Fun that you use type(x) to report the type 🙂 because it's meant for rel-types.

Thanks!

Yah, I couldn't remember the apoc method to return the property type, so I just tried type(x) on the fly. Of course, it complained but it was also useful. Incidentally, apoc.meta.type(x) returns "INTEGER" in both cases, so doing it the wrong way saved me some time scratching my head.