优化密码查询以避免笛卡尔积

时间:2016-02-23 16:49:17

标签: neo4j query-optimization cypher cartesian-product

查询目的非常简单。对于给定的nodeId(userId),我想在图上返回在X跳中具有关联的所有节点,并且我想聚合并返回它们之间的距离(关系上设置的参数))

我想出了这个:

MATCH p=shortestPath((user:FOLLOWERS{userId:{1}})-[r:follow]-(f:FOLLOWERS)) " +
                        "WHERE f <> user " +
                        "RETURN (f.userId) as userId," +                     
                        "reduce(s = '', rel IN r | s + rel.dist + ',') as dist," +
                        "length(r) as hop"

userId({1})作为输入给出并被编入索引。

我相信我在这里有笛卡尔产品。你会怎么建议避免它?

1 个答案:

答案 0 :(得分:2)

您可以通过在:FOLLOWERS(userId)上创建索引来加快笛卡尔产品的繁重程度,从而加快两条腿中的一条腿#34;笛卡尔积:

CREATE INDEX ON :FOLLOWERS(userId);

即使这不会消除笛卡尔积,它也会在O(N log N)时间内运行,这比O(N ^ 2)快得多。

顺便说一句,您的r关系需要是可变长度的,以便查询正常工作。您应该指定一个合理的上限(取决于您的数据库),以确保查询将在合理的时间内完成,而不是耗尽内存。例如:

MATCH p=shortestPath((user:FOLLOWERS { userId: 1 })-[r:follow*..5]-(f:FOLLOWERS))
WHERE f <> user
RETURN (f.userId) AS userId,
  REDUCE (s = '', rel IN r | s + rel.dist + ',') AS dist,
  LENGTH(r) AS hop;