我正在尝试编写查询以查找具有outdegree X的所有节点,并且仅当路径长度等于Y时才返回包含这些节点的路径
如果我只想获得具有outdegree 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
每当我执行查询时,机器会继续处理,然后我得到一个没有足够内存的错误。
好像有一个无限循环!
答案 0 :(得分:1)
如果您只想对遍历关系感兴趣,可以将其包含在路径表达式中:
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
你应该看到一些性能提升,因为现在路径长度&gt; 7将被排除在结果之外,它们将不会被遍历。同样,总是避免无限深度遍历,除非有一个非常好的理由,并且您有足够的计算机资源+时间来完成查询。
关于性能最佳实践,此查询仍然无法很好地执行,因为它强制图形扫描查找起始节点。我知道标记为URL的节点包含类型为Array的属性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