在Neo4j中,对于每个不相交的子图,返回关系最多的节点

时间:2015-10-12 09:18:29

标签: neo4j cypher graph-theory

我是Neo4j和图论的新手,我想弄清楚我是否可以使用Neo4j来解决我遇到的问题。如果我用错误的词语描述东西,请纠正我。由于我是这个主题的新手,所以我并没有真正地围绕着什么称呼所有东西。

我认为描述我的问题的最简单方法是使用大量图片。 假设你有两个不相交的子图,看起来像这样。

enter image description here

从上面的子图中我想得到满足两个标准之一的子图列表。

标准1。 如果节点与另一个节点具有唯一关系,则应将节点和关系作为子图返回。

标准2。 如果关系不是唯一的,我希望返回具有最多关系的节点,作为具有关系和相关节点的子图。

如果其他节点与标准2相符,我希望返回所有子图。

或者放在此图的上下文中,

给我那些拥有独特游戏的人,如果有其他人拥有相同的游戏,请给我一个游戏最多的人。如果他们打成平手,那就归还所有领带的人。 或者实际上,返回整个子图,而不仅仅是人。

为了澄清我在这之后的是一张描述我想要得到的结果的图片。结果的排序并不重要。

enter image description here

脱节的子图A,由于标准1,安德鲁是唯一拥有泡泡龙的人。

不相交的子图B,因为标准1,Johan是唯一拥有Puzzle Bobble 1的人。

由于标准2,朱莉亚,因为她拥有最多的游戏,所以不相交子图C.

由于标准2,安娜因为与朱莉娅打成比赛次数最多,因此脱节了D小节。

值得注意的是,Johan与Puzzle Bobble 2的关系没有被退回,因为它并不是唯一的,而且他没有最多的游戏。

这是一个只能用Neo4j解决的问题,这是一个好主意吗?

如果你能解决它,你将如何在Cypher中完成?

创建脚本:

  CREATE  (p1:Person {name:"Johan"}),
      (p2:Person {name:"Julia"}),
      (p3:Person {name:"Anna"}),
      (p4:Person {name:"Andrew"}),

      (v1:Videogame {name:"Puzzle Bobble 1"}),
      (v2:Videogame {name:"Puzzle Bobble 2"}),
      (v3:Videogame {name:"Puzzle Bobble 3"}),
      (v4:Videogame {name:"Puzzle Bobble 4"}),
      (v5:Videogame {name:"Bubble Bobble"}),

       (p1)-[:HAS]->(v1),
       (p1)-[:HAS]->(v2),

       (p2)-[:HAS]->(v2),
       (p2)-[:HAS]->(v3),
       (p2)-[:HAS]->(v4),

       (p3)-[:HAS]->(v2),
       (p3)-[:HAS]->(v3),
       (p3)-[:HAS]->(v4),

       (p4)-[:HAS]->(v5)

1 个答案:

答案 0 :(得分:1)

我觉得这个解决方案可能不是你想要的,但它可能是一个好的开始:

MATCH (game:Videogame)<-[:HAS]-(owner:Person)
OPTIONAL MATCH owner-[:HAS]->(other_game:Videogame)
WITH game, owner, count(other_game) AS other_game_count
ORDER BY other_game_count DESC
RETURN game, collect(owner)[0]

这里是查询:

  • 查找所有游戏及其所有者(没有所有者的游戏将无法匹配)
  • OPTIONAL MATCH对那些所有者可能拥有的任何其他游戏(通过做一个可选的匹配,我们说如果他们拥有零就没关系)
  • 通过每个游戏/所有者对以及该所有者拥有的其他游戏数量的计数,进行排序,以便那些拥有最多游戏的人排在第一位
  • RETURN每个游戏的第一个所有者(执行ORDER时保留collect