Match a relationship for each element in a collection (Neo4j 2.0)

499 views
Skip to first unread message

Rory Madden

unread,
Nov 4, 2013, 9:43:14 AM11/4/13
to ne...@googlegroups.com
Is it possible to MATCH relationships for collections returned from a PATH?

My cypher is as follows:
START person=node({id})
MATCH path = person-[:PARENT|CHILD|COUPLE]-(:Relationship)-[:PARENT|CHILD|COUPLE*1..100]-(:Person)
WITH 
FILTER(r in NODES(path) WHERE r:Relationship) AS relNodes, RELATIONSHIPS(path) AS rels, TAIL(FILTER(p in NODES(path) WHERE p:Person)) AS people
RETURN relNodes, EXTRACT(r in relNodes | id(r)) AS relNodesId, LAST(EXTRACT(r in rels | type(r))) AS RelType, people, EXTRACT(p in people | id(p)) AS peopleId

This cypher gives me a list of all of the paths connecting from the start person to the related people. However I want to be able to MATCH other nodes related to the Relationship nodes returned and the Person nodes returned. I have tried to run:
MATCH relNodes-[:FACT]->(fact), people-[:NAME]->(name)
but this does not work as relNodes and people are Collections of nodes. 

I might be structuring the query in the wrong way. If so any guidance would be appreciated.

Thanks,
Rory

Lisa

unread,
Nov 4, 2013, 10:28:01 AM11/4/13
to ne...@googlegroups.com
Instead of matching the nodes in the collections, you might add the identifiers to the nodes to be matched to the additional patterns, and add these additional patterns to the "Match" clause directly like this, 

 MATCH path = person-[:PARENT|CHILD|COUPLE]-(relNodes:Relationship)-[:PARENT|CHILD|COUPLE*1..100]-(people:Person), relNodes-[:FACT]->(fact), people-[:NAME]->(name)

Michael Hunger

unread,
Nov 4, 2013, 11:25:47 AM11/4/13
to ne...@googlegroups.com
Your Relationship is the people relationship, right?

Perhaps a picture of your model would help.

You kind of need unwind.

You can use relNodes in a path expression though (was possible in 1.9 and again after M06, I can send you a snapshot).

This: relNodes-[:FACT]->() then results in a collection of paths.

return extract(relNode in relNodes | extract( p in relNodes-[:FACT]->() | last(p))) as facts

Michael

--
You received this message because you are subscribed to the Google Groups "Neo4j" group.
To unsubscribe from this group and stop receiving emails from it, send an email to neo4j+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Rory Madden

unread,
Nov 5, 2013, 5:44:01 AM11/5/13
to ne...@googlegroups.com
Thanks for your responses, I've attached some pictures of the data model to give you a better idea.

Lisa: I tried your approach but unfortunately the facts are always returning null even though they exist in the model. I'm not sure why?
START person=node({id})
MATCH path = person-[:PARENT|CHILD|COUPLE]-(rel:Relationship)-[:PARENT|CHILD|COUPLE*]-(person2:Person), rel-[:FACT]->(fact), person2-[:NAME_FORM]-name
WITH FILTER(r in NODES(path) WHERE r:Relationship) AS relNodes, RELATIONSHIPS(path) AS rels, TAIL(FILTER(p in NODES(path) WHERE p:Person)) AS people, fact, name
RETURN relNodes, EXTRACT(r in relNodes | id(r)) AS relNodesId, collect(fact), LAST(EXTRACT(r in rels | type(r))) AS RelType, people, EXTRACT(p in people | id(p)) AS peopleId, collect(name)


Michael: I'm trying your approach but the change in the latest version to OPTIONAL MATCH has broken a lot of things so I'll reply back once I've gotten everything working again. 

Thanks for your help,
Rory
Sample Data.png
Data Model.png
Screenshot 2013-11-05 10.40.33.png

Lisa

unread,
Nov 5, 2013, 8:41:56 AM11/5/13
to ne...@googlegroups.com
It returns null because there is no relationship [:NAME_FORM] attached to the node :Person, hence there is no node person2 that would match this pattern person2-[:NAME_FORM]-name. If you change it to person2:[NAME]->name, it should return the desired result.
Reply all
Reply to author
Forward
0 new messages