Geohash Roll up Graph (level 5) from (level 7)

cypher

(Haddadahmed1994) #1

I am trying to create a geohash graph with level 5 of zoom from an existing one with level 7. i tried this code :

 FROM GRAPH mergedGraph
 MATCH (from)-[via]->(to)
 CASE WHEN substring(from.geohash,0,5)=substring(to.geohash,0,5)
 THEN
 CONSTRUCT
 CREATE (h:HashNode{geohash:substring(from.geohash,0,5)})-[COPY OF via]->  (h)
 ELSE
 CONSTRUCT create (:HashNode{geohash:substring(from.geohash,0,5)})-[COPY OF via]->(:HashNode{geohash:substring(to.geohash,0,5)})
 END
 RETURN GRAPH

however i get an exception :

 Caused by: org.opencypher.v9_0.util.SyntaxException: Invalid input 'S': expected 'l/L' (line 4, column 4 (offset: 57))

In english words i want : if the start node and the end node share the same geohash substring then create one node with the relationship that point back to it:
2018-09-28
else create two nodes :
2018-09-28%20(1)
NB : The project i am working at is CYPHER FOR APACHE SPARK


(Michael Hunger) #2

Graph construction (Cypher 10) is not yet in Neo4j. Where did you find the syntax?

You could use apoc.create.vNode(['HashNode'],{geohash:substring(from.geohash,0,5)})
and apoc.create.vRelationship(from,'TYPE,{},to) instead.

I don't understand why you create in the first case a HashNode relationship to itself?

I just typed this from my head but it should work.

MATCH (node)
WITH distinct substring(node.geohash,0,5) as hash
WITH apoc.map.fromPairs(collect([hash,apoc.create.vNode(['HashNode'], {geohash:hash})])) as vNodes
MATCH (from)-[via]->(to)
WITH substring(from.geohash,0,5) as fromHash, substring(to.geohash,0,5) as toHash, vNodes
WHERE fromHash <> toHash
WITH vNodes[fromHash] as from,vNodes[toHash] as to
RETURN from, to, apoc.create.vRelationship(from,'VIA',{}, to);

Let me know if this worked.


(Haddadahmed1994) #3

Hello @micheal, the project i work at is Cypher for Apache Spark , we can create graphs with construct .
for apoc it is a user defined function , user defined functions don't work in CAPS.
for more details i have updated my question


(Haddadahmed1994) #4

I solved my problem with this steps:

  1. Create a graph with Level 5 from the existing one :
//Creation Geohash Graph with level 5 from the initial graph (level 7)
   val Level5 = session.cypher("""
                      | FROM GRAPH mergeGraph
                      | MATCH (from)-[via]->(to)
                      | CONSTRUCT
                      |  CREATE (:HashNode{geohash:substring(from.geohash,0,5)})-[COPY OF via]->(:HashNode{geohash:substring(to.geohash,0,5)})
                      | RETURN GRAPH
                      """.stripMargin).graph
  1. Copy distant nodes from the previous graph :

    session.cypher ("""
    | CATALOG CREATE GRAPH nodes2 {
    | FROM GRAPH session.Level5
    | MATCH (n)
    | WITH DISTINCT n.geohash AS geohash
    |CONSTRUCT
    | CREATE (h:HashNode{geohash:geohash})
    |RETURN GRAPH
     }""".stripMargin)
    

finally:

  1. Create the distant level5 graph by copying relationships from the first one and affecting them to the distant nodes
val level5= session.cypher("""
                               FROM GRAPH Level5
                              |  MATCH (from)-[via]->(to)
                              |  FROM GRAPH nodes2
                              |  MATCH (n), (m)
                              |  WHERE from.geohash=n.geohash AND to.geohash = m.geohash
                               construct
                              |    CREATE (n)-[COPY OF via]->(m)
                              |  RETURN GRAPH
                           """.stripMargin).graph