Path Manipulation

The functions in this section can be used to create, combine and split paths.

Function Overview

The available functions are described below:

type qualified name signature description

function

apoc.path.create

apoc.path.create(startNode :: NODE?, rels = [] :: LIST? OF RELATIONSHIP?) :: (PATH?)

apoc.path.create(startNode,[rels]) - creates a path instance of the given elements

function

apoc.path.combine

apoc.path.combine(first :: PATH?, second :: PATH?) :: (PATH?)

apoc.path.combine(path1, path2) - combines the paths into one if the connecting node matches

function

apoc.path.slice

apoc.path.slice(path :: PATH?, offset = 0 :: INTEGER?, length = -1 :: INTEGER?) :: (PATH?)

apoc.path.slice(path, [offset], [length]) - creates a sub-path with the given offset and length

function

apoc.path.elements

apoc.path.elements(path :: PATH?) :: (LIST? OF ANY?)

apoc.path.elements(path) - returns a list of node-relationship-node-…​

Examples

The examples in this section are based on the following sample graph:

MERGE (manUtd:Club {name: 'Man Utd'})
MERGE (juventus:Club {name: 'Juventus'})
MERGE (flamengo:Club {name: 'Flamengo'})

MERGE (premierLeague:League {name: 'Premier League'})
MERGE (serieA:League {name: 'Serie A'})
MERGE (brasileirao:League {name: 'Brasileirão'})

MERGE (england:Country {name: 'England'})
MERGE (brazil:Country {name: 'Brazil'})

MERGE (uefa:Confederation {name: 'UEFA'})

MERGE (manUtd)-[:IN_LEAGUE]->(premierLeague)
MERGE (premierLeague)-[:IN_COUNTRY]->(england)
MERGE (england)-[:IN_CONFEDERATION]->(uefa)

MERGE (juventus)-[:IN_LEAGUE]->(serieA)

MERGE (flamengo)-[:IN_LEAGUE]->(brasileirao)
MERGE (brasileirao)-[:IN_COUNTRY]->(brazil);

The apoc.path.create function creates paths from a start node and a list of relationhips. One use case for this function is combining relationships from OPTIONAL MATCH clauses.

The following query creates a path from relationships returned by OPTIONAL MATCH clauses
MATCH (club:Club)
OPTIONAL MATCH (club)-[inLeague:IN_LEAGUE]->(league)
OPTIONAL MATCH (league)-[inCountry:IN_COUNTRY]->(country)
OPTIONAL MATCH (country)-[inConfederation:IN_CONFEDERATION]->(confederation)
RETURN club.name, apoc.path.create(club, [inLeague, inCountry, inConfederation]) AS path
ORDER BY length(path);
Table 1. Results
club.name path

"Juventus"

(:Club {name: "Juventus"})-[:IN_LEAGUE]→(:League {name: "Serie A"})

"Flamengo"

(:Club {name: "Flamengo"})-[:IN_LEAGUE]→(:League {name: "Brasileirão"})-[:IN_COUNTRY]→(:Country {name: "Brazil"})

"Man Utd"

(:Club {name: "Man Utd"})-[:IN_LEAGUE]→(:League {name: "Premier League"})-[:IN_COUNTRY]→(:Country {name: "England"})-[:IN_CONFEDERATION]→(:Confederation {name: "UEFA"})

If we want to create a path from a query that contains two OPTIONAL MATCH clauses, we can instead use the apoc.path.combine function.

The following returns a path that combines the (club)-[:IN_LEAGUE]→(league) and (league)-[:IN_COUNTRY]→(country) paths
MATCH (club:Club)
OPTIONAL MATCH path1 = (club)-[:IN_LEAGUE]->(league)
OPTIONAL MATCH path2 = (league)-[:IN_COUNTRY]->(country)
RETURN club.name, apoc.path.combine(path1, path2) AS path
ORDER BY length(path);
Table 2. Results
club.name path

"Juventus"

(:Club {name: "Juventus"})-[:IN_LEAGUE]→(:League {name: "Serie A"})

"Man Utd"

(:Club {name: "Man Utd"})-[:IN_LEAGUE]→(:League {name: "Premier League"})-[:IN_COUNTRY]→(:Country {name: "England"})

"Flamengo"

(:Club {name: "Flamengo"})-[:IN_LEAGUE]→(:League {name: "Brasileirão"})-[:IN_COUNTRY]→(:Country {name: "Brazil"})

The apoc.path.slice function returns a subset of a path starting from a specified offset for a specified number of elements.

The following returns a subset of the combined path, starting from an offset of 1 for a length of 1
MATCH (club:Club)
OPTIONAL MATCH path1 = (club)-[:IN_LEAGUE]->(league)
OPTIONAL MATCH path2 = (league)-[:IN_COUNTRY]->(country)
WITH apoc.path.combine(path1, path2) AS path
RETURN apoc.path.slice(path, 1, 1);
Table 3. Results
apoc.path.slice(path, 1, 1)

(:League {name: "Premier League"})-[:IN_COUNTRY]→(:Country {name: "England"})

(:League {name: "Serie A"})

(:League {name: "Brasileirão"})-[:IN_COUNTRY]→(:Country {name: "Brazil"})

The apoc.path.elements function converts a path into a list of nodes and relationships.

The following returns a list of entities in the (club)-[:IN_LEAGUE]→(league)-[:IN_COUNTRY]→(country) path
MATCH path = (club:Club)-[:IN_LEAGUE]->(league)-[:IN_COUNTRY]->(country)
RETURN path, apoc.path.elements(path);
Table 4. Results
path apoc.path.elements(path)

(:Club {name: "Man Utd"})-[:IN_LEAGUE]→(:League {name: "Premier League"})-[:IN_COUNTRY]→(:Country {name: "England"})

[(:Club {name: "Man Utd"}), [:IN_LEAGUE], (:League {name: "Premier League"}), [:IN_COUNTRY], (:Country {name: "England"})]

(:Club {name: "Flamengo"})-[:IN_LEAGUE]→(:League {name: "Brasileirão"})-[:IN_COUNTRY]→(:Country {name: "Brazil"})

[(:Club {name: "Flamengo"}), [:IN_LEAGUE], (:League {name: "Brasileirão"}), [:IN_COUNTRY], (:Country {name: "Brazil"})]

We can use this function to return a stream of triples representing the nodes and relationships contained in paths.

The following returns triples of (subject, predicate, object)
MATCH path = (club:Club)
OPTIONAL MATCH path1 = (club)-[:IN_LEAGUE]->(league)
OPTIONAL MATCH path2 = (league)-[:IN_COUNTRY]->(country)
WITH apoc.path.combine(path1, path2) AS path
WITH apoc.path.elements(path) AS elements
UNWIND range(0, size(elements)-2) AS index
WITH elements, index
WHERE index %2 = 0
RETURN elements[index] AS subject, elements[index+1] AS predicate, elements[index+2] AS object;
Table 5. Results
subject predicate object

(:Club {name: "Man Utd"})

[:IN_LEAGUE]

(:League {name: "Premier League"})

(:League {name: "Premier League"})

[:IN_COUNTRY]

(:Country {name: "England"})

(:Club {name: "Juventus"})

[:IN_LEAGUE]

(:League {name: "Serie A"})

(:Club {name: "Flamengo"})

[:IN_LEAGUE]

(:League {name: "Brasileirão"})

(:League {name: "Brasileirão"})

[:IN_COUNTRY]

(:Country {name: "Brazil"})