ChrisR
ChrisR

Reputation: 14457

Cypher match nodes with less that X relations of a given type

Given this data I would like to cypher query the neo4j database for all users that have less that X friends where X is their own friend_limit property. I've tried several COUNT queries but failed to get consistent results.

For example in this case I'd like to receive a resultset with all users except Joe (who 2 out of 2 friends) and Ella (how has 1 out of 1).

CREATE 
(Joe:User { name:'Joe', friend_limit:2 }),
(James:User {name: 'James', friend_limit:2}),
(Jack:User {name: 'Jack', friend_limit:2}),
(Jane:User {name: 'Jane', friend_limit:2}),
(Ella:User {name: 'Ella', friend_limit:1}),
(Ann:User {name: 'Ann', friend_limit:2}),

(Joe)-[:FRIENDS_WITH]->(Ella),
(Joe)-[:FRIENDS_WITH]->(James),
(James)-[:FRIENDS_WITH]->(Jack),
(Ella)-[:FRIENDS_WITH]->(Jane)

http://console.neo4j.org/r/gbnw5s


Edit: i've come as far as this but I can't find a way to also include Ann in the resultset, she probably is missing because she doesn't have any FRIENDS_WITH relation thus fails the MATCH part?

MATCH (n:User)-[r:FRIENDS_WITH]-(u:User) 
WITH n, count(r) AS nr_of_friends 
WHERE nr_of_friends < n.friend_limit 
RETURN n, n.friend_limit, nr_of_friends

http://console.neo4j.org/r/vjy1lt

Upvotes: 1

Views: 378

Answers (2)

tekiegirl
tekiegirl

Reputation: 1315

I would do it in a similar way to @Luanne, just a little more concisely:

MATCH (u:User) 
OPTIONAL MATCH (u)-[:FRIENDS_WITH]-(f:User) 
WITH u, count(f) AS friendCount 
WHERE friendCount < u.friend_limit 
RETURN u, friendCount

I have left f:User because I think it makes it a little more efficient, especially if the model changed at a later date so that a User could be friends with something other than a user (but that would probably have a different relationship type anyway).

Upvotes: 1

Luanne
Luanne

Reputation: 19373

MATCH (u:User) 
WITH u 
OPTIONAL MATCH (u:User)-[:FRIENDS_WITH]-(f:User) 
WITH u, count(f) AS friendCount 
WHERE friendCount < u.friend_limit 
RETURN u, friendCount

works (use an Optional Match to get Ann). Though I had to first do match all using

MATCH (u:User) 
WITH u 

not sure if there is a better way to do that

Upvotes: 3

Related Questions