Home > database >  Get nodes and relationships at a given hop from a Neo4j graph
Get nodes and relationships at a given hop from a Neo4j graph

Time:07-19

I want to query a Neo4j graph for nodes and their relationships at a given hop from a root node. I could get the nodes using apoc.neighbors.byhop, though not sure how I can get relationships between nodes.

Specifically, in the following graph, I'm interested to know that A is connected to C through B1 or B2. The output of apoc.neighbors.byhop does not seem to contain this information.

enter image description here

merge (p1:Person {label:"A"})
merge (p2:Person {label:"B1"})
merge (p3:Person {label:"B2"})
merge (p4:Person {label:"C"})
merge (p1)-[:Knows]->(p2)
merge (p1)-[:Knows]->(p3)
merge (p2)-[:Knows]->(p4)

To retrieve nodes at an n-hop distance:

match (p:Person {label:"A"})
call apoc.neighbors.byhop(p, "Knows", 3) 
yield nodes 
return nodes

Which returns an object as the following that does not include relationship information.

[
   [
      {
         "identity":11,
         "labels":[
            "Person"
         ],
         "properties":{
            "label":"B1"
         }
      },
      {
         "identity":12,
         "labels":[
            "Person"
         ],
         "properties":{
            "label":"B2"
         }
      }
   ],
   [
      {
         "identity":0,
         "labels":[
            "Person"
         ],
         "properties":{
            "label":"C"
         }
      }
   ]
]

I'm interfacing with Neo4j through its .NET driver.

CodePudding user response:

That APOC function (apoc.neighbors.byhop) only returns nodes and NOT relationships. I tried replicating the same APOC function and returns the relationships in the path.

MATCH path=(p:Person {label:"A"})-[:Knows*1..]->(p2:Person)
WITH [n in nodes(path) where n <> p | n] as nodes, relationships(path) as relationships 
WITH size(nodes) as cnt, collect(nodes[-1]) as nodes, collect(distinct relationships[-1]) as relationships 
RETURN nodes, relationships

Below is the result:

[
  {
    "nodes": [
      {
        "identity": 2,
        "labels": [
          "Person"
        ],
        "properties": {
"label": "B1"
        }
      },
      {
        "identity": 3,
        "labels": [
          "Person"
        ],
        "properties": {
"label": "B2"
        }
      }
    ],
    "relationships": [
      {
        "identity": 0,
        "start": 1,
        "end": 2,
        "type": "Knows",
        "properties": {

        }
      },
      {
        "identity": 1,
        "start": 1,
        "end": 3,
        "type": "Knows",
        "properties": {

        }
      }
    ]
  },
  {
    "nodes": [
      {
        "identity": 4,
        "labels": [
          "Person"
        ],
        "properties": {
"label": "C"
        }
      }
    ],
    "relationships": [
      {
        "identity": 2,
        "start": 2,
        "end": 4,
        "type": "Knows",
        "properties": {

        }
      }
    ]
  }
]

CodePudding user response:

Something like this in pure Cypher will show you all relationships between nodes. You can tweak the node properties and relationship names as you'd like.

MATCH path = (p:Person)-[*1..]->(p2:Person) RETURN p, relationships(path), p2

  • Related