优化密码查询以避免笛卡尔积
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;
查询目的很简单。对于给定的 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;