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

Optimize cypher query to avoid cartesian product

查询目的很简单。对于给定的 nodeId(userId) 我想在图表上 return 所有在 X 跳内有关系的节点,我想聚合和 return 它们之间的距离(设置关系的参数)

我想到了这个:

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}) 作为输入给出并被编入索引。

我相信我这里有笛卡尔积。你建议如何避免它?

您可以通过在 :FOLLOWERS(userId) 上创建索引来加速笛卡尔积的两个 "legs" 之一,从而使笛卡尔积不那么繁重:

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;