cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! Site migration is underway. Phase 2: migrate recent content

Shortest path excluding nodes with same attribute value

Meryem_dba
Node

Hi,

I found out that I can use shortest path and avoid loops by applying apoc.coll.duplicates on path nodes list.

What if I want to consider duplicates those nodes that share the same value for a given attribute (e.g. ALTER_NAME).
Would be possible to apply a DISTINCT on the nodes values and doing something like
WHERE apoc.coll.duplicates(NODES(path).ALTER_NAME) = []?

 

MATCH (source:POINT {NAME: 'A'}), (target:POINT {NAME: 'B'})
CALL gds.shortestPath.dijkstra.stream('mygraph', {
    sourceNode: source,
    targetNode: target,
    relationshipWeightProperty: 'miles'
})
YIELD index, sourceNode, targetNode, totalCost, nodeIds, costs, path
WHERE apoc.coll.duplicates(NODES(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

 

 

1 ACCEPTED SOLUTION

glilienfield
Ninja
Ninja

You can do what your suggest, but you need to extract the ALTER_NAME values from the nodes first to use in the apoc.coll.duplicates function:

MATCH (source:POINT {NAME: 'A'}), (target:POINT {NAME: 'B'})
CALL gds.shortestPath.dijkstra.stream('mygraph', {
    sourceNode: source,
    targetNode: target,
    relationshipWeightProperty: 'miles'
})
YIELD index, sourceNode, targetNode, totalCost, nodeIds, costs, path
WITH index, sourceNode, targetNode, totalCost, nodeIds, costs, path, [x in nodes(path) | x.ALTER_NAME] as alter_names
WHERE apoc.coll.duplicates(alter_names) = []
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

View solution in original post

1 REPLY 1

glilienfield
Ninja
Ninja

You can do what your suggest, but you need to extract the ALTER_NAME values from the nodes first to use in the apoc.coll.duplicates function:

MATCH (source:POINT {NAME: 'A'}), (target:POINT {NAME: 'B'})
CALL gds.shortestPath.dijkstra.stream('mygraph', {
    sourceNode: source,
    targetNode: target,
    relationshipWeightProperty: 'miles'
})
YIELD index, sourceNode, targetNode, totalCost, nodeIds, costs, path
WITH index, sourceNode, targetNode, totalCost, nodeIds, costs, path, [x in nodes(path) | x.ALTER_NAME] as alter_names
WHERE apoc.coll.duplicates(alter_names) = []
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
Nodes 2022
Nodes
NODES 2022, Neo4j Online Education Summit

All the sessions of the conference are now available online