dominiktomicevic
dominiktomicevic

Reputation: 87

Filtering nodes related to specific nodes in cypher

How can one filter all nodes connected to some set of nodes efficiently?

I have this for now:

MATCH (:City { Id: 10 })<-[:LIVES_IN]-(p:Person),
p-[:KNOWS]->(:Person { Name: 'John' }),
p-[:KNOWS]->(:Person { Name: 'Mark' }),
p-[:KNOWS]->(:Person { Name: 'Jane' }),
p-[:KNOWS]->(:Person { Name: 'Mary' })
RETURN p

And this does what I want but it's very slow. It takes about 900ms on a database with approx. 500 nodes labeled as Person.

The problem I want to solve is even bigger

MATCH (:City { Id: 10 })<-[:LIVES_IN]-(p:Person)-[:HAS_ITEM]->(i:Item),
p-[:KNOWS]->(:Person { Name: 'John' }),
p-[:KNOWS]->(:Person { Name: 'Mark' }),
p-[:KNOWS]->(:Person { Name: 'Jane' }),
p-[:KNOWS]->(:Person { Name: 'Mary' })
RETURN i, count(p)

This query finds people that have items and for each item, it returns the count of all people that have that item and also know certain people. This query never finishes (or I didn't wait long enough).

When I remove the 'know certain people' part, the query finishes in about 400ms.

MATCH (:City { Id: 10 })<-[:LIVES_IN]-(p:Person)-[:HAS_ITEM]->(i:Item),
RETURN i, count(p)

What am I doing wrong?

Upvotes: 3

Views: 329

Answers (1)

Eve Freeman
Eve Freeman

Reputation: 33145

Try reordering it to minimize the number of results it has to search through at a time. Something like this--if knows groups are smaller than the number of people that live in the city and the number of people who have items, then this might even be better (if the people who have items is pretty low, can swap it around):

MATCH (p:Person)-[:KNOWS]->(:Person { Name: 'John' }) // start with john's friends
WITH p
MATCH (:City { Id: 10 })<-[:LIVES_IN]-(p)-[:HAS_ITEM]->(i:Item) // only friends that live in city 10 and have the item...
WITH p, i
MATCH p-[:KNOWS]->(:Person { Name: 'Mark' })
WITH p, i
MATCH p-[:KNOWS]->(:Person { Name: 'Jane' })
WITH p, i
MATCH p-[:KNOWS]->(:Person { Name: 'Mary' })
RETURN i, count(p)

Also, make sure you have an index on :Person(Name) and :City(Id)

Upvotes: 3

Related Questions