Is there an option to get the relationship properties on a shortest path

Hey there,

this is my first experience with the neo4j database. And i am a really beginner in it. But i think i got the most things working for now. But now i have a problem. I try to get the shortest path from a source to a target node, but i need properties from the relation.

Our nodes are in the Format:

CREATE (:NodeType {name: 'A'})
CREATE (:NodeType {name: 'B'})

Then our relations are:

MATCH (n:NodeType {name: 'A'}),(m:NodeType {name: 'B'})
CREATE (n)-[:UPGRADE {description: 'climb above the tree', price: 5.5}]->(m)
MATCH (n:NodeType {name: 'A'}),(m:NodeType {name: 'B'})
CREATE (n)-[:UPGRADE {description: 'go around the forest', price: 7.5}]->(m)

Each relation has an own description, and this description is relevant to us. So we try to get the shortest path from our graph with this information.

We try the following:

CALL gds.graph.project(
    'neo4j',
    'NodeType',
    'UPGRADE',
    {
        relationshipProperties: 'price',
    }
)

And after this we used:

MATCH (source:NodeType {name: 'A'}), (target:NodeType {name:'B'})
CALL gds.shortestPath.yens.stream('neo4j', {
    sourceNode: source,
    targetNode: target,
    k: 2,
    relationshipWeightProperty: 'price'
})
YIELD index, sourceNode, targetNode, totalCost, nodeIds, costs, path
RETURN
    index,
    gds.util.asNode(sourceNode).name AS sourceNodeName,
    gds.util.asNode(targetNode).name AS targetNodeName,
    totalCost,
    [nodeId IN nodeIds | gds.util.asNode(nodeId).name] AS nodeNames,
    costs,
    nodes(path) as path
ORDER BY index

This works really fine, i get the shortest path in a form of a table. But i can not get the "description" information for the relations. But i need them as well.
Is there any solution or any trick that i can get the shortest path with the information of the relation properties ? So that i can put this information on the result ?

Thank you :slight_smile:

here is how you can return the description properties of the relationships in path

[x in relationships(path) |x.description]

hey,

i tried it, but i became only as result then [null,null,nuill]
i think this is because the projection did not know the properties? But i am not sure.
Even if i take a look at the "path" on the query, without the "nodes()" context. I get in the "segments" section of the result only the "price" property, but not the other ones :frowning:

If you look at the path list you will notice that the relationships have negative id values. As such, they are not the true relationships. It looks like they are virtual relationships and the only property is the 'cost' used in the shortest path algorithm.

You can add some code to get the relationships between each node along each path and extract the 'description' property (or other properties) from each relationship. Of course, this assumes there is only one relationship with type 'UPGRADE' between each node. Assuming the assumption is true, you can add the following 'COLLECT' subquery to your RETURN statement to get the list of descriptions along each path. The collect subquery is a new feature in version 5.6. Subquery expressions are a powerful addition. There are three of them exists, count, and collect.

MATCH (source:NodeType {name: 'A'}), (target:NodeType {name:'B'})
CALL gds.shortestPath.yens.stream('neo4j', {
    sourceNode: source,
    targetNode: target,
    k: 2,
    relationshipWeightProperty: 'price'
})
YIELD index, sourceNode, targetNode, totalCost, nodeIds, costs, path
RETURN
    index,
    gds.util.asNode(sourceNode).name AS sourceNodeName,
    gds.util.asNode(targetNode).name AS targetNodeName,
    totalCost,
    [nodeId IN nodeIds | gds.util.asNode(nodeId).name] AS nodeNames,
    costs,
    nodes(path) as path,
    COLLECT {
        WITH nodes(path) as pathNodes
        UNWIND range(0,size(pathNodes)-2) as i
        WITH pathNodes[i] as a, pathNodes[i+1] as b
        MATCH (a)-[r:UPGRADE]-(b)
        RETURN r.description
    }
ORDER BY index

Note, the value of 'path' defined in the 'RETURN' statement is not the same as the value of 'path' used in the 'COLLECT' subquery, as the 'nodes(path) as path' does not take affect until AFTER the 'RETURN' or 'WITH' statement. As such, the value of 'path' used in the collect subquery is still the one defined in the 'yield' statement. I would use a different variable node for 'path' in 'nodes(path) as path' to avoid confusion.

1 Like

Cool, thank you :) so i need to read the complete things about the virtual relations. Thank you so much for the example, and the explanations.
So i need to read more documentation at all :)
Again. Thank you

1 Like