Cypher无方向查询不返回所有预期路径

时间:2015-07-28 19:39:29

标签: neo4j cypher

我有一个从机器节点开始的密码查询,并尝试使用我指定的任何关系类型查找与之相关的节点:

match p1=(n:machine)-[:REL1|:REL2|:REL3|:PERSONAL_PHONE|:MACHINE|:ADDRESS*]-(n2)
where n.machine="112943691278177215"
optional match p2=(n2)-[*]->()
return p1,p2
limit 300

optional match子句是我尝试从p1中的每个节点向我的模型中向外遍历。下面的屏幕截图显示了我遇到问题的部分结果:

initial results

您可以从启动计算机节点看到,它通过与计算机相关的两个应用程序节点找到个人电话节点。为了澄清,模型的这一部分设计如下:

model

所以出现一直工作,直到我意识到某些路径被某种方式排除在结果之外。如果我运行第二个查询向我显示与该特定个人电话节点相关的所有应用程序,我会收到以下信息:

match p1=(n:personal_phone)<-[*]-(n2)
where n.personal_phone="(xxx) xxx-xxxx"
return p1
limit 100

personal_phone

我分割出的两个应用是前面图片中显示的两个应用。

那么为什么我的原始查询不能显示与personal_phone相关的其他7个应用程序?

编辑:尽管可选匹配过于宽泛且与limit 300语句相结合,但返回的结果仅显示52个节点和154个rels。这是因为跟随向外方向的关系的路径将很快停止。我本来可以放一个最大的2但是很懒。

编辑2 :我最终提出的问题是给我我想要的是:

match p1=(m:machine)<-[:MACHINE]-(a:app)
where m.machine="112943691278177215"
optional match p2=(a:app)-[:REL1|:REL2|:REL3|:PERSONAL_PHONE|:MACHINE|:ADDRESS*0..3]-(n)
where a<>n and a<>m and m<>n
optional match p3=(n)-[r*]->(n2)
where n2<>n
return distinct n, r, n2 

这将返回74个节点和220个rels,这似乎是正确的结果(387行)。所以看起来我的查询非常低效是图表被截断的原因。不仅节点被遍历多次,而且返回的路径包含重复信息,这些信息消耗了可用于返回的有限行。我想我的新问题是:

  1. 当遵循多跳时,我是否应该始终明确确保不通过where子句遍历相同的节点?
  2. 如果我改为return p3,则返回1941行以显示74个节点和220个rels。似乎存在很多重复。通常更好的方法是使用return distinct(就像我上面的那样),还是有办法轻松地重复删除路径中的节点和关系?

1 个答案:

答案 0 :(得分:1)

因此,您的问题的一部分(更新的问题)是您返回路径,而不是单个节点/关系。

例如,如果您执行MATCH p=(n)-[*]-()且数据为A->B->C->D,那么您获得的结果将为A->B, A->B->C, A->B->C->D,依此类推。另一方面,如果你做了MATCH (n)-[r:*]-(m)然后使用rm,你可以获得相同的数据,但是处理路径上的不同内容而不是必须对其进行排序以后出去。

似乎你想要节点和关系,但是你要求路径 - 所以你得到它们。 全部。 :)

  

当遵循多跳时,我是否应该始终明确确定   不通过where子句遍历相同的节点?

嗯,你这样做的方式,是的 - 但说实话,我以前从未遇到过这个问题。部分问题是您正在运行的过于宽泛的查询。没有任何约束,它最终会在你已经匹配的项目中使用,这会给你带来这个问题。也许更好的方法是匹配一些可能的标签,以缩小查询范围。通过缩小范围,您将不会遇到同样的问题,例如:

MATCH (n)-[r:*]-(m)
WHERE 'foo' in labels(m) or 'bar' in labels(m)
RETURN n, r, m;

请注意,我们没有进行路径匹配,我们指定的某些标签范围可能是m,而不会完全偏离西方。我倾向于以这种方式制定查询,所以你的问题#2从未真正产生过。大概你有一个合理的数据模型可以作为你的基础。