找到具有特定长度的路径与具有特定度neo4j的节点相结合

时间:2015-04-13 13:01:52

标签: neo4j cypher graph-databases

我正在尝试编写查询以查找具有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

每当我执行查询时,机器会继续处理,然后我得到一个没有足够内存的错误。

好像有一个无限循环!

1 个答案:

答案 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