subvertallchris
subvertallchris

Reputation: 5482

Neo4j: Cypher match where node has property OR has relationship

I feel like I'm overlooking something obvious here but just to be sure. Starting with this query:

match (e:Event), (u:User)
where (e.status = 'public' XOR (e)<-[:`can_access`*1..2]-(u) AND u.id = '541c7a8797b272f708000001')
return e

That returns all events that are either public or accessible by up to two degrees from the user across the "can_access" relationship. It works as expected.

Is this the best way to approach this? I'm unable to use a relationship identifier in the where clause, so I'll theoretically take a performance hit over time.

Upvotes: 1

Views: 772

Answers (1)

FrobberOfBits
FrobberOfBits

Reputation: 18022

The way you're doing it looks fine, but if you're looking for alternative suggestions, you could do this. The main thing is to move most of your WHERE into the MATCH block instead:

MATCH (e:Event {status: "public"})
RETURN e

UNION

MATCH (e:Event)<-[:`can_access`*1..2]-(u:User {id: '541c7a8797b272f708000001'})
RETURN e;

Now, this ignores your XOR bit, so I suppose it's possible something is both public, and accessible via can_access. In that case, your query would exclude such a result, and mine would include it. But based on the semantics of your query, I'm guessing this is OK and you didn't really need the XOR. If the XOR is important, then you could always separately weed out the nodes that happen to meet both criteria, or otherwise fix the linkages so both conditions don't simultaneously hold.

Upvotes: 1

Related Questions