2017-07-03 81 views
6

我有一个Neo4j的图形看起来像这样间的任意路径:暗号:查找节点

Graph overview

节点:

  1. 蓝色节点:帐户
  2. 红色节点:******中国
  3. 绿色节点:电子邮件

图形设计:

  • (:******中国) - [:PART_OF] - >(:帐户)
  • (:电子邮件) - [:PART_OF] - >(:帐户)

我试图解决的问题是

查找帐户1和帐户2之间存在任何路径。

这是我一直没有成功到目前为止已经试过:

  1. MATCH P =最短路径((A1:帐户{ACCID: '1234'}) - [] - (A2:帐户{ accId:'5678'}))RETURN p;
  2. MATCH p = shortestPath((a1:Account {accId:'1234'}) - [:PART_OF] - (a2:Account {accId:'5678'}))RETURN p;
  3. MATCH p = shortestPath((a1:Account {accId:'1234'}) - [*] - (a2:Account {accId:'5678'}))RETURN p;
  4. MATCH p =(a1:Account {accId:'1234'})< - [:PART_OF * 1..100] - (n) - [:PART_OF] - >(a2:Account {accId:'5678' })RETURN p;
  5. 与上面相同的查询没有最短路径函数调用。

通过查看图我可以看到这两个节点之间存在路径,但是我的查询中没有任何结果存在。我确信这是一个非常简单的查询,但对Cypher来说是新的,我很难找出正确的解决方案。任何帮助表示赞赏。

谢谢。

+0

您能否提供更多关于运行这些查询时会发生什么的细节? –

回答

4

所有这些查询都沿着正确的路线,但需要一些调整才能完成工作。然而,从长远来看,为了获得更好的系统来轻松搜索帐户之间的连接,您可能需要重构图形。

解决方案现在:使你的查询工作

在图形中任意两个(n:Account)节点之间的路径将会是这个样子:

(a1:Account)<-[:PART_OF]-(:Email)-[:PART_OF]->(ai:Account)<-[:PART_OF]-(:PhoneNumber)-[:PART_OF]->(a2:Account)

因为你只有一次类型的关系在图中,两个节点因此将通过如下的不确定数目的模式连接:

<-[:PART_OF]-(:Email)-[:PART_OF]->

<-[:PART_OF]-(:PhoneNumber)-[:PART_OF]->

所以,你的两个节点将通过所有通过交替方向的-[:PART_OF]-关系连接中间(:Account)(:Email),或(:PhoneNumber)节点的数目不确定连接。不幸的是,据我所知(我很想在这里纠正),使用直接密码,你不能在你当前的图表中搜索这样的重复模式。因此,您只需使用无向搜索,即可找到通过-[:PART_OF]-关系连接的节点(a1:Account)(a2:Account)。所以,乍一看您的查询应该是这样的:

MATCH p=shortestPath((a1:Account { accId: {a1_id} })-[:PART_OF*]-(a2:Account { accId: {a2_id} })) 
RETURN * 

(注意这里我用cypher parameters,而不是你把在原岗位的整数)

这是非常相似的查询#3 ,但是,就像你说的那样 - 它不起作用。我猜测会发生什么,它不会返回结果,或返回内存不足异常?问题是由于你的图有循环路径,并且该查询将匹配任何长度的路径,所以匹配算法将逐字地绕圈,直到它耗尽内存。所以,你想设置一个限制,就像你在查询#4中,但没有方向(这就是为什么该查询不起作用)。

所以,我们设置一个限制。 100个关系的限制在很大的一方有一点点,特别是在一个循环图(即一个包含圆的图)中,并且可能在2^100个路径的区域内匹配。作为(非常随意的)经验法则,任何查询的潜在无向和未标记的路径长度超过5或6可能会导致问题,除非您对图形设计非常小心。在你的例子中,它看起来像这两个节点通过8的路径长度连接。我们还知道,对于任何两个节点,给定的最小路径长度将是两个(即两个-[:PART_OF]-关系,一个进入和一个进出一个节点标记为:Email:PhoneNumber),并且任何两个帐户(如果已链接)都将通过偶数关系进行关联。

因此,理想情况下我们要设定我们的关系长度在2到10之间。但是,密码的shortestPath()函数只支持最小长度为0或1的路径,所以我在1和10之间设置了它。下面的例子(尽管我们知道实际上最短路径的长度至少为2)。

MATCH p=shortestPath((a1:Account { accId: {a1_id} })-[:PART_OF*1..10]-(a2:Account { accId: {a2_id} })) 
RETURN * 

希望,这会影响您使用的情况下工作,但要记住,它可能仍然是非常内存密集型,以在大图运行。

更长远的解决方案:重构图和/或使用APOC

根据你的使用情况,更好或更长期的解决办法是重构你的图形来具体谈谈关系,以加快查询时间当你想查找仅通过电子邮件或电话号码链接的账户 - 即-[:ACCOUNT_HAS_EMAIL]--[:ACCOUNT_HAS_PHONE]-。然后,您可能还想使用APOC的shortest path algorithmspath finder functions,这将最有可能返回比使用密码更快的结果,并且允许您更详细地描述关系类型,因为图形扩展以获取更多数据。

+1

感谢大教堂,这工作像魅力。我现在明白了我的Graph设计中的基本缺陷。我会纠正设计并尝试APOC。以前从未尝试过。再次感谢。 – Agandalf