Neo4j Cypher:获得共同的朋友网络

时间:2013-03-01 02:31:42

标签: graph neo4j cypher gremlin

我相信我拥有的应该是非常直截了当的,但由于某种原因,我没有前进。我有经典的社交网络设置,用户可以成为彼此的朋友。我知道想用D3.js

来想象用户的网络

为此,它明显如何得到朋友

user -[:friend]- friend

现在,我还希望在用户的朋友之间显示连接,以便在强制导向图中很好地聚类。然而,这是我目前的问题,因为我想知道“朋友”集是如何相互联系的。我首先想到了

with friend
match friend -[connection:friend]- friend

会起作用,但显然不会。我似乎忽略了一个非常明显的事情,但我不确定是什么。

编辑:格雷姆林也很受欢迎,如果更多的遍历/明确可能会更高效

1 个答案:

答案 0 :(得分:0)

也许这会激发你使用Gremlin的解决方案。我将您的问题改编为标准的TinkerPop玩具图。我开始着手解决以下问题:

对于特定顶点,找到它所连接的所有顶点,然后查看该总集中每个顶点如何相互关联。根据您的描述,这听起来像您正在寻找的。

所以我开始:

gremlin> g = TinkerGraphFactory.createTinkerGraph()              
==>tinkergraph[vertices:6 edges:6]
gremlin> g.v(1).outE.as('x').inV.loop(2){it.loops<3}{true}.select
==>[x:e[7][1-knows->2]]
==>[x:e[8][1-knows->4]]
==>[x:e[9][1-created->3]]
==>[x:e[10][4-created->5]]
==>[x:e[11][4-created->3]]

对于id为1的顶点,获取所有out边缘然后再次循环以获取朋友边缘,最后选择“x”步骤的值。这让你至少知道g.v(1)周围的子图是什么,但是当我读到你的问题时,你想进一步将子图限制为只连接到g.v(1)的那些顶点。看结果,e [10]确实不应该包括在内,因为g.v(1)和g.v(5)之间没有边缘。

我进一步完善了查询以消除子图中的关系:

gremlin> x=[g.v(1)];g.v(1).out.aggregate(x).back(2).outE.filter{x.contains(it.inV.next())}.as('e').inV.loop(3){it.loops<3}{true}.select 
==>[e:e[7][1-knows->2]]
==>[e:e[8][1-knows->4]]
==>[e:e[9][1-created->3]]
==>[e:e[11][4-created->3]]

所以上面基本上说,

  • 初始化一个列表x,它将包含应该保存在子图中的所有顶点。
  • g.v(1).out.aggregate(x)基本上将我想要的所有顶点放在子图中,除了我用
  • 初始化它的那个顶点之外
  • 回溯到遍历的开始并查找包含x中顶点的outEdges然后像以前一样循环它并选择“e”步骤的值,即边缘列表。

现在你可以看到e [10]不再出现在结果中了。从这里,您可以非常轻松地构建用于可视化的输出。