0
votes

having some problems with cypher query and numeric indexes

@Indexed(unique = true, numeric = false)
private Long accountId;

Returns:

neo4j-sh (0)$ start n=node:Principal(accountId = '1') return n;      
+---------------------------------------------------------------------------------------------+
| n                                                                                           |
+---------------------------------------------------------------------------------------------+
| Node[41722]{__type__:"example.package.Principal",accountId:1,name:"Simple User"} |
+---------------------------------------------------------------------------------------------+
1 row

But

@Indexed(unique = true, numeric = true)
private Long accountId;

Returns:

neo4j-sh (0)$ start n=node:Principal(accountId = '1') return n; 
+---+
| n |
+---+
+---+
0 row

neo4j 1.9.2
spring-data-neo4j 2.3.0.RC1

If i understand correctly this might be ralted this discussion, but it is quite old?

UPDATE:

If i use

@Indexed(unique = true, numeric = false)

Another interesting thing happens. Checking if relationship exists (it actualy exists in db):

count(r) is equal to 0 - incorrect:

Long accountId = 1L;
Map<String, Object> result = template.query(
        "START child=node:Principal(accountId='{childId}') " +
                "MATCH child-[r:IS_MEMBER_OF]->parent " +
                "RETURN count(r)", MapUtil.map("childId", accountId)).singleOrNull();

count(r) is equal to 1 - correct:

Long accountId = 1L;
Map<String, Object> result = template.query(
        "START child=node:Principal(accountId='1') " +
                "MATCH child-[r:IS_MEMBER_OF]->parent " +
                "RETURN count(r)",null).singleOrNull();
1

1 Answers

1
votes

Numeric index lookups don't work from cypher with literal values, the lucene parser doesn't create the correct internal queries. Also with parameters, normal primitive values passed to the index are treated as strings in the neo4j lucene implementation as the query cannot know if the data was indexed numerically or as string.

// this won't work, you have to remove the single quotes around '{childId}'
"START child=node:Principal(accountId='{childId}') " +

    "MATCH child-[r:IS_MEMBER_OF]->parent " +
    "RETURN count(r)", MapUtil.map("childId", accountId)).singleOrNull();

The only way you get numeric queries to work with cypher is to pass in a ValueContext.numeric(1) value as parameter in a java-parameter-map to an embedded database.