过滤与cypher中特定节点相关的节点

时间:2014-07-06 19:24:13

标签: neo4j cypher

如何有效地过滤连接到某组节点的所有节点?

我现在有这个:

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

这就是我想要的,但它很慢。大约需要900毫秒的数据库。标记为Person的500个节点。

我想解决的问题更大

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)

此查询查找具有项目的人员,并且对于每个项目,它返回具有该项目的所有人员的计数,并且还知道某些人员。这个查询永远不会完成(或者我没等多久)。

当我删除“知道某些人”部分时,查询将在大约400毫秒内完成。

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

我做错了什么?

1 个答案:

答案 0 :(得分:3)

尝试对其进行重新排序,以最大限度地减少一次搜索所需的结果数量。这样的事情 - 如果知道群体小于居住在城市的人数和拥有物品的人数,那么这甚至可能更好(如果有物品的人很少,可以交换它):

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)

另外,请确保您在:Person(Name):City(Id)

上有索引