Creating virtual elements from output of apoc.path.expand

I want to create a virtual relationship from the output of apoc.path.expand. I assumed I could feed in the output to the second part of the query using WITH, but don't know if/how to access graph elements as apoc.path.expand only yields a path? (apologies if I'm missing something obvious).

Thanks in advance

MATCH (c:Company) where c.name = "PRECISE ADVICE PARTNERSHIP LLP"
call apoc.path.expand(c, "CONCERNS", "", 0, 6) yield path
WITH ??
MATCH (co:CompanyOfficer)<-[:CONCERNS]-(:Event)-[:CONCERNS]->(c1:Company)
WITH co, c1
CALL apoc.create.vRelationship(c1,'CONNECTED_TO',{}, co) YIELD rel
RETURN co, c1, rel

Hi Mike,

What are you attempting to get out of the results?

You can use nodes(path) to get a collection of nodes that make up the path (per path), or you can use relationships(path) to get a collection of relationships that make up the path (per path).

If you need just the last node of each path, you can use last(nodes(path)).

Hi Andrew, thanks for stepping in.

The expand query returns this

Pink nodes are companies, yellow company officers. There are connected by intermediate nodes 'Events' which hold properties such as dates. I want to present a virtual graph representation where the intermediate nodes are removed. There is a common relationship type, 'CONCERNS', which connects all nodes in this subgraph.

I can create the desired output structure with this query

MATCH (co:CompanyOfficer {surname: 'OATEN'})<-[:CONCERNS]-(:Event)-[:CONCERNS]->(c:Company)
WITH co, c
CALL apoc.create.vRelationship(c,'CONNECTED_TO',{}, co) YIELD rel
RETURN co, c, rel
LIMIT 10

Which returns

Just can't do so from the output of apoc.path.expand. I played around with nodes(path) and relationships(path) but no joy.

I am assuming I've got the sequencing right, i.e. produce the subgraph and then 'virtualise' it?

Thanks

Hi Andrew, forgot to reply to you just posted in the thread... always learning!

So this is a tad tricky. We need to get ahold of relationships in the path, and from those with the common start node (which will be :Event nodes), gather the distinct end nodes (:CompanyOfficer and :Company nodes), then create the vNodes between those nodes.

If every :Event node only connects a pair of these nodes, this kind of query should work:

MATCH (c:Company) where c.name = "PRECISE ADVICE PARTNERSHIP LLP"
call apoc.path.expandConfig(c, {maxLevel:6, relationshipFilter:'CONCERNS', uniqueness:'RELATIONSHIP_GLOBAL'}) YIELD path
UNWIND relationships(path) as rel
WITH DISTINCT rel
WITH startNode(rel) as event, collect(DISTINCT endNode(rel)) as toConnect
WITH toConnect[0] as toConnect1, toConnect[1] as toConnect2
CALL apoc.create.vRelationship(toConnect1,'CONNECTED_TO',{}, toConnect2) YIELD rel
RETURN toConnect1, rel, toConnect2

I'm using expandConfig() here as this adds some additional options, and by using RELATIONSHIP_GLOBAL uniqueness I minimize the number of times each relationship is traversed, then I get the DISTINCT rels so I don't process the same relationship multiple times.

If an :Event node can connect > 2 other nodes, then we'll need to adjust the query to get all possible pairs of toConnect nodes to create the vRelationship between each pair. Let me know if you need an example of that approach.

EDIT: fixed a small error in my query, it was originally collecting startNodes of the relationships, but we want to collect the endNodes instead.

1 Like

Cheers Andrew, I'll give it a bash
Mike

Andrew, yes now works a treat after that edit. Thank you again.

Hi Andrew,

We've since rebuilt our data model and I have been reworking queries. I've been working on this expand query and am stuck :frowning:

I need to either group or created virtual nodes or relationships for the duplicates so only one node/rel is visualised. (I do not want to merge the underlying nodes/rels, they need to persist in the db).

In this example:
the small green nodes need to be grouped, there is a property 'personnumber' available to use.
there are four rels that need the same treatment, but if you could help with one example?

Here's the current query:

MATCH (co:CompanyOfficer)-[HAS_FORENAMES]-(fn:ForeNames)
where fn.text STARTS WITH "JACOB"
MATCH (co)-[HAS_SURNAME]-(sn:Surname)
WHERE  sn.text = "REES-MOGG"
call apoc.path.expandConfig(co, {maxLevel:6, relationshipFilter:'CONCERNS|HAS_SURNAME|HAS_FORNAME', labelFilter: '/Surname|/ForeNames', uniqueness:'RELATIONSHIP_GLOBAL'}) YIELD path
UNWIND relationships(path) as rel
WITH DISTINCT rel
WITH startNode(rel) as event, collect(DISTINCT endNode(rel)) as toConnect
WITH toConnect[0] as toConnect1, toConnect[1] as toConnect2
CALL apoc.create.vRelationship(toConnect1,'CONNECTED_TO',{}, toConnect2) YIELD rel
RETURN toConnect1, rel, toConnect2
LIMIT 300

Any help would be fab.
Cheers,
Mike

1 Like