找到具有特定长度的路径与具有特定度数的节点 neo4j
find paths with specific length combined with nodes with specific degree neo4j
我正在尝试编写查询以查找出度为 X 的所有节点,并且仅 return 路径长度等于 Y 时包含这些节点的路径
如果我只想获取出度为 X 的节点,我使用以下 Cypher 查询
MATCH (s:URL)-[r:VISITED*]->(t:URL)
WITH s, count(t) as degreeout
WHERE 73 in s.job_id and degreeout <4
return s, degreeout
如果我只想获取长度为 X 的路径,我使用以下查询
MATCH p=(s:URL)-[r:VISITED*]->(t:URL)
WHERE length(p)=7
return p
我尝试在以下查询中组合前两个查询
MATCH (s:URL)-[r:VISITED*]->(t:URL)
WITH s, COLLECT(DISTINCT id(s)) as matched, count(t) as degreeout
WHERE 73 in s.job_id and degreeout <4
MATCH p=(s2:URL)-[r:VISITED*]-(t2:URL)
WHERE id(s2) in matched and length(p) >=1
RETURN p
每当我执行查询时,机器一直在处理,然后我收到内存不足的错误消息。
好像是无限循环!!
如果您只对遍历关系的确切次数感兴趣,您可以将其包含在路径表达式中:
MATCH p=(s:URL)-[r:VISITED*7]->(t:URL)
return p
一般来说,你应该避免进行无限长度的遍历,即 :VISITED*
。如果你想保留深度变量,因为它是未知的,最好设置一个最大值。值,即 :VISITED*..7
.
如果我没理解错的话,你原来的查询是可以调整的,只要在路径中将变量长度设置为7即可:
MATCH (s:URL)-[r:VISITED*7]->(t:URL)
WITH s, count(t) as degreeout
WHERE 73 in s.job_id and degreeout <4
return s, degreeout
您应该会看到一些性能改进,因为现在长度 > 7 的路径将从结果中排除,并且不会遍历它们。同样,始终避免无限深度遍历,除非有充分的理由并且您有足够的计算机资源和时间来完成查询。
关于性能最佳实践,此查询仍然不会执行得很好,因为它强制进行图扫描以找到起始节点。我知道标记为 URL 的节点包含一个 属性 job_id
类型的数组,因为 in
运算符? Neo4j 需要读取所有 URL 个节点及其属性,然后扫描这些数组以找到起始节点。
我建议更改您的数据模型以使用基于精确 属性 值的架构索引。示例:
(j:Job {job_id: 73})-[:SOMETHING?]->(u:URL {...})
我们还会添加模式索引:
CREATE INDEX ON :Job(job_id)
那么你可以这样查询:
MATCH (j:Job {job_id: 73})-[:SOMETHING?]->(s:URL)-[r:VISITED*7]->(t:URL)
WITH s, count(t) as degreeout
WHERE degreeout <4
return s, degreeout
我正在尝试编写查询以查找出度为 X 的所有节点,并且仅 return 路径长度等于 Y 时包含这些节点的路径
如果我只想获取出度为 X 的节点,我使用以下 Cypher 查询
MATCH (s:URL)-[r:VISITED*]->(t:URL)
WITH s, count(t) as degreeout
WHERE 73 in s.job_id and degreeout <4
return s, degreeout
如果我只想获取长度为 X 的路径,我使用以下查询
MATCH p=(s:URL)-[r:VISITED*]->(t:URL)
WHERE length(p)=7
return p
我尝试在以下查询中组合前两个查询
MATCH (s:URL)-[r:VISITED*]->(t:URL)
WITH s, COLLECT(DISTINCT id(s)) as matched, count(t) as degreeout
WHERE 73 in s.job_id and degreeout <4
MATCH p=(s2:URL)-[r:VISITED*]-(t2:URL)
WHERE id(s2) in matched and length(p) >=1
RETURN p
每当我执行查询时,机器一直在处理,然后我收到内存不足的错误消息。
好像是无限循环!!
如果您只对遍历关系的确切次数感兴趣,您可以将其包含在路径表达式中:
MATCH p=(s:URL)-[r:VISITED*7]->(t:URL)
return p
一般来说,你应该避免进行无限长度的遍历,即 :VISITED*
。如果你想保留深度变量,因为它是未知的,最好设置一个最大值。值,即 :VISITED*..7
.
如果我没理解错的话,你原来的查询是可以调整的,只要在路径中将变量长度设置为7即可:
MATCH (s:URL)-[r:VISITED*7]->(t:URL)
WITH s, count(t) as degreeout
WHERE 73 in s.job_id and degreeout <4
return s, degreeout
您应该会看到一些性能改进,因为现在长度 > 7 的路径将从结果中排除,并且不会遍历它们。同样,始终避免无限深度遍历,除非有充分的理由并且您有足够的计算机资源和时间来完成查询。
关于性能最佳实践,此查询仍然不会执行得很好,因为它强制进行图扫描以找到起始节点。我知道标记为 URL 的节点包含一个 属性 job_id
类型的数组,因为 in
运算符? Neo4j 需要读取所有 URL 个节点及其属性,然后扫描这些数组以找到起始节点。
我建议更改您的数据模型以使用基于精确 属性 值的架构索引。示例:
(j:Job {job_id: 73})-[:SOMETHING?]->(u:URL {...})
我们还会添加模式索引:
CREATE INDEX ON :Job(job_id)
那么你可以这样查询:
MATCH (j:Job {job_id: 73})-[:SOMETHING?]->(s:URL)-[r:VISITED*7]->(t:URL)
WITH s, count(t) as degreeout
WHERE degreeout <4
return s, degreeout