AnormCypher: How to get a complete path for a given node?

271 views Asked by At

For a graph consisting of two groups of nodes:

n1 -> n2 -> n3 -> n4

and

n5 -> n6 -> n7

Created with commands:

CREATE (n1 { id:'n1' })-[:rel]->(n2 {id:'n2' })-[:rel]->(n3 { id:'n3' })-[:rel]->(n4 {id:'n4'})

CREATE (n5 { id:'n5' })-[:rel]->(n6 {id:'n6' })-[:rel]->(n7 { id:'n7' })

For both requests:

MATCH p = (n {id: 'n1'})-[*]-(m) RETURN nodes(p) as nodes;

MATCH p = (n {id: 'n1'})-[*]-(m) RETURN relationships(p) as rels ;

AnormCypher (http://anormcypher.org/) returns info related only to nodes n1 and n2, while Neo4J Web console returns a complete path.

How to get all nodes and relations for the complete path in AnormCypher?

Program that demonstrates this (at the end of this message) outputs:

ListBuffer(NeoNode(32,Map(id -> n1)), NeoNode(33,Map(id -> n2)))
Node: id=32 props=Map(id -> n1)
--Props keys:
----key: id val: n1
Node: id=33 props=Map(id -> n2)
--Props keys:
----key: id val: n2
ListBuffer(NeoRelationship(27,Map(),32,33))
Rel: id=27 start=32 end=33 props=Map()

Code:

object Simple {
   def main(args: Array[String]): Unit = {

Cypher("MATCH p = (n {id: 'n1'})-[*]-(m) RETURN nodes(p) as nodes;")().map { row =>

  println(row[Seq[org.anormcypher.NeoNode]]("nodes"))
  val nodes = row[Seq[org.anormcypher.NeoNode]]("nodes")

  nodes.map(n => {
    val props = n.props
    println("Node: id="+n.id+" props="+props)
    println("--Props keys: ")
    val x = props.keys
    props.keys.map( k=> println("----key: "+k+" val: "+props(k)))
    })
}

Cypher("MATCH p = (n {id: 'n1'})-[*]-(m) RETURN relationships(p) as rels ;")().map { row =>

  println(row[Seq[NeoRelationship]]("rels"))
  val rels = row[Seq[NeoRelationship]]("rels")
  rels.map(r => {
    val x = r.props
    println("Rel: id="+r.id+" start="+r.start+" end="+r.end+" props="+r.props)
  })
}

 }
}
1

There are 1 answers

3
Eve Freeman On BEST ANSWER

The problem is your map function is creating a lazy stream, and you're not iterating over the rest of the stream. If you add .toList or .last to the end of your .map, forcing the iteration over the full stream, you should get the longer path results.

For example:

Cypher("MATCH p = (n {id: 'n1'})-[*]-(m) RETURN nodes(p) as nodes;")().map { row =>
  println(row[Seq[org.anormcypher.NeoNode]]("nodes"))
  val nodes = row[Seq[org.anormcypher.NeoNode]]("nodes")

  nodes.map(n => {
    val props = n.props
    println("Node: id="+n.id+" props="+props)
    println("--Props keys: ")
    val x = props.keys
    props.keys.map( k=> println("----key: "+k+" val: "+props(k)))
    })
}.toList

Alternatively, you could just use .foreach instead of .map, which does this for you.

Update: Here's an example that has no return type:

Cypher("MATCH p = (n {id: 'n1'})-[*]-(m) RETURN nodes(p) as nodes;")().foreach { row =>
  println(row[Seq[org.anormcypher.NeoNode]]("nodes"))
  val nodes = row[Seq[org.anormcypher.NeoNode]]("nodes")

  nodes.map(n => {
    val props = n.props
    println("Node: id="+n.id+" props="+props)
    println("--Props keys: ")
    val x = props.keys
    props.keys.map( k=> println("----key: "+k+" val: "+props(k)))
    })
}