限制每个标签的节点

时间:2014-09-03 11:47:05

标签: neo4j cypher graph-databases

我有一个图表,目前有几千个节点,每个节点有两到十个关系。如果我们查看单个节点及其连接,它们看起来有点像: Node and relating nodes

具有字母字符的节点是类别节点。所有其他节点是与这些类别节点具有associated with关系的内容节点,并且它们的颜色表示将哪个(哪些)标签附加到其上。为简单起见,每个节点都有一个标签,每个节点只连接到一个其他节点:

  • 蓝色:分类
  • 绿色:科学出版物
  • 橙色:一般文章
  • 紫色:博客帖子

现在,我尝试做的最简单的事情是将一定数量的相关内容节点添加到给定节点。以下内容返回所有20个相关节点:

START n = node(1)
MATCH (n)-->(category)<--(m)
RETURN m

但是,我想将每个类别的每个标签过滤到2个节点(然后通过具有多个类别与起始节点重叠的节点进行排序。

目前我通过从上面的查询中获取结果,然后手动循环查看结果来做到这一点,但这对我来说就像是多余的工作。

有没有办法通过Neo4j的密码查询语言来做到这一点?

2 个答案:

答案 0 :(得分:3)

Cypher有一个labels函数返回一个包含给定节点所有标签的数组。假设每个m节点只有一个标签,则以下方法可以起作用:

START n = node(1)
MATCH (n)-->(category)<--(m)
WITH labels(m)[0] as label, collect[m][0..2] as nodes 
UNWIND nodes as n
RETURN n

WITH语句构建了共享相同标签的所有节点的单独集合。使用下标运算符[0..2],集合只保留前两个元素。然后Unwind将集合转换为结果的单独行。从这里开始,您可以申请订购。

答案 1 :(得分:3)

这个答案扩展了@Stefan的原始答案,以返回所有类别的结果,而不仅仅是其中一个。

START p = node(1)
MATCH (p)-->(category)<--(m)
WITH category, labels(m) as label, collect(m)[0..2] as nodes 
UNWIND label as lbl
UNWIND nodes AS n
RETURN category, lbl, n

为便于手动验证结果,您还可以将此行添加到最后,以对结果进行排序。 (这种排序可能不应该在你的最终代码中,除非你真的需要排序结果并愿意花费额外的计算时间):

ORDER BY id(category), lbl