cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! Site migration is underway. Phase 1: replicate users.

Getting relationship properties of shortest path

GregH
Node

Hi,

I'm running Dijkstra's algorithm to find the shortest path between two nodes

    MATCH (source:Node {{nodeId: 123 }}), (target:Node {{nodeId: 456 }})
    CALL gds.shortestPath.dijkstra.stream('undirectedGraph', {{
        sourceNode: source,
        targetNode: target,
        relationshipWeightProperty: 'cost'
    }})
    YIELD index, sourceNode, targetNode, totalCost, nodeIds, costs, path
    
    return path
    

Once I have the shortest path, I need to access some additional properties that I have stored at each edge (relationship) on that path. Unfortunately, this has proved much harder than I feel it should be.

The "path" variable is just a list of the nodes visited on the path and doesn't refer at all to the edges. I tried searching based on the path, e.g.

MATCH (n[path[i]]) - [e] - (n[path[i+1]])
return e.propterty

But I can't get the syntax in terms of iterating over path at i&i+1. Any suggestions for that would be greatly appreciated - or hopefully just a much easier alternative.

3 REPLIES 3

glilienfield
Ninja
Ninja

A true path entity will have nodes and relationships. You can get the list of relationships from path ‘p’ using relationships(p). Each relationship consists of a startNode, endNode, properties, and type. You can access each with a method of the same name.

I would agree with you but path returned by "gds.shortestPath.dijkstra.stream" doesn't seem to fit the pattern. Here's how I defined my graph

CALL gds.graph.project.cypher(
  'undirectedGraph',
  'MATCH (n:Node) RETURN id(n) AS id',
  'MATCH (n:Node)-[r:Edge]-(p:Node) RETURN id(n) AS source, id(p) AS target, r.traversalTime AS cost,1 as test'
)
YIELD graphName

I then run dijkstra's algorithm and iterate over the relationships on the returned path.

def query(source,target):

    query = f"""
    MATCH (source:Node {{nodeId: {source} }}), (target:Node {{nodeId: {target} }})
    CALL gds.shortestPath.dijkstra.stream('undirectedGraph', {{
        sourceNode: source,
        targetNode: target,
        relationshipWeightProperty: 'cost'
    }})
    YIELD index, sourceNode, targetNode, totalCost, nodeIds, costs, path
    
    return relationships(path) as r,totalCost
    
        
    """
    
    df = pd.DataFrame(graph_3.run(query).data())
    
    for t in df["r"].values[0]:
        print(t["cost"])

query(-570795,-471951)

I can get the "cost" property for each relationship in the path but if I switched to t["test"], all of the values are None.

I see what you mean. From what I read in the docs for Dijkstra algorithm, it returns a virtual relationship with the cost attribute. As such, it doesn’t seem to include other projected relationship properties.

looks like you can get all the relationships and properties projected with the following method

https://neo4j.com/docs/graph-data-science/current/graph-catalog-relationship-ops/