Max Yari
Max Yari

Reputation: 3707

Neo4j match nodes that are in relationship with one OR another node

I'm trying to wrap my head around one query. For example I have this pattern (photo:Photo)-[:AUTHOR]->(user:User). User can have friends (user:User)-[:FRIEND]->(friend:User). So how can i make a query in which i will find all :Photos made by me or my friends and sort them by date if there is any?

MATCH (user:User {id: 'me'}), (user)-[:FRIEND]-(friend:User)
//other pattern matches that I need to do
OPTIONAL MATCH (photo:Photo)-[:AUTHOR]-(user | friend)
RETURN photo
ORDER BY photo.date
LIMIT 42

But as far as I know this costruct (user | friend) is invalid. So what's correct way to do that?

Upvotes: 2

Views: 646

Answers (1)

Martin Preusse
Martin Preusse

Reputation: 9369

If you only look for a single relationship to a defined User node, a simple way would be to use a variable length relationship with length 0 to 1. This collects all nodes with a distance of 0 (which is you start node) and all nodes with a distance of 1.

MATCH (user:User {id: 'me'})-[:FRIEND*0..1]-(me_and_friend:User)
OPTIONAL MATCH (photo:Photo)-[:AUTHOR]-(me_and_friend)
RETURN photo
ORDER BY photo.date
LIMIT 42

A more generic solution would be to collect different nodes into arrays, combine these arrays and then use UNWIND to MATCH again:

MATCH (user:User {id: 'me'}), (user)-[:FRIEND]-(friend:User)
WITH collect(user)+collect(friend) AS me_and_friends
UNWIND me_and_friends AS allusers
OPTIONAL MATCH (photo:Photo)-[:AUTHOR]-(allusers)
RETURN photo
ORDER BY photo.date
LIMIT 42

This could be useful if you MATCH longer paths or more complex patterns.

Upvotes: 4

Related Questions