Reputation: 9
I have two nodes, "client" and "builder". I want to find only the relationships where the client only has 1 builder, and that builder only has that one client so a 1-1 relationship. So far my query is
MERGE(b:Person{name:csv.name)
MERGE(c:Person{name:csv.name})
WITH collect(distinct b) as builder, collect(distinct c) as client
UNWIND builder as builders
UNWIND client as clients
WITH builders, clients
WHERE builders = 1 and clients = 1
MATCH (builders:Person)-[bu:builder_for]->(clients:Person)
WITH builders,clients, count(distinct bu) as builds
WHERE builds=1
RETURN distinct builders, clients
This only returns though a 1 to many relationship and is still showing duplicates in my client list.
The highlighted are the ones I would want to return
UPDATE cybersam implementation worked, thank you so much!
Upvotes: 0
Views: 678
Reputation: 67044
Assuming you want to get all the builder
/client
pairs that only have a single builder_for
relationship between them, this query uses the aggregating function COUNT
to do that:
MATCH (builder:Person)-[rel:builder_for]->(client:Person)
WITH builder, client, COUNT(rel) AS rel_count
WHERE rel_count = 1
RETURN builder, client;
[UPDATE]
If, instead, you want builder
/client
pairs in which the builder
has only that one client
, and vice versa, then this query should work:
MATCH (builder:Person)
WHERE SIZE((builder)-[:builder_for]->()) = 1
MATCH (builder)-[:builder_for]->(client:Person)
WHERE SIZE(()-[:builder_for]->(client)) = 1
RETURN builder, client;
This query uses efficient relationship degree-ness checks (in the WHERE
clauses) to ensure that the builder
and client
nodes only have, respectively, a single outgoing or incoming builder_for
relationship.
Upvotes: 1