Neo4j:计算属于两个不同连接类别的项目



我想计算和比较两个连接类别的项目数量,但数字似乎不匹配。

假设我有一个图表,例如:

CREATE (o1:Object {name:"CategoryA"})-[:CONNECTS_TO]->(o2:Object {name:"CategoryB"}),
(i1:Instance {name:"Item1"})-[:IS_A]->(o1),
(i2:Instance {name:"Item2"})-[:IS_A]->(o2),
(i3:Instance {name:"Item3"})-[:IS_A]->(o2)

其中,对象 1 连接到对象 2,同时对象 1 与项1 关联,对象 2 与项 2 和项 3 关联。

然后我想计算每个对象的项目数:

MATCH (o1:Object)-[:CONNECTS_TO]->(o2:Object),
(ix)-[:IS_A]->(o1), 
(iy)-[:IS_A]->(o2) 
WITH o1, o2, COUNT(ix) AS o1_count, COUNT(iy) AS o2_count 
RETURN o1.name, o1_count, o2.name, o2_count

我本来期望的结果是:

"CategoryA" 1   "CategoryB" 2

但实际上我得到:

"CategoryA" 2   "CategoryB" 2

有人可以告诉我我做错了什么吗?

如果您只返回匹配结果,则可以看到发生了什么:

MATCH (o1:Object)-[:CONNECTS_TO]->(o2:Object),
(ix)-[:IS_A]->(o1), 
(iy)-[:IS_A]->(o2)
RETURN o1, o2, ix, iy

你会得到这个:

╒════════════════════╤════════════════════╤════════════════╤════════════════╕
│"o1"                │"o2"                │"ix"            │"iy"            │
╞════════════════════╪════════════════════╪════════════════╪════════════════╡
│{"name":"CategoryA"}│{"name":"CategoryB"}│{"name":"Item1"}│{"name":"Item3"}│
├────────────────────┼────────────────────┼────────────────┼────────────────┤
│{"name":"CategoryA"}│{"name":"CategoryB"}│{"name":"Item1"}│{"name":"Item2"}│
└────────────────────┴────────────────────┴────────────────┴────────────────┘

正好有两种模式适合您的匹配,这些模式的唯一区别是哪个节点用于iy。模式中的其余节点是相同的。

对于此处的完整查询,由于有两种可能的模式,其中o1o2相同(这些是非聚合变量(,因此每个计数将为 2(只是对于其中一个,ix,每次都是同一个节点(。

您真正想要的是模式中不同节点的计数:

MATCH (o1:Object)-[:CONNECTS_TO]->(o2:Object),
(ix)-[:IS_A]->(o1), 
(iy)-[:IS_A]->(o2) 
WITH o1, o2, COUNT(distinct ix) AS o1_count, COUNT(distinct iy) AS o2_count 
RETURN o1.name, o1_count, o2.name, o2_count

这样可以获得所需的结果,因为找到的路径中只有一个不同的ix节点,而找到的路径中有两个不同的iy节点。

更好的方法是甚至不使用计数聚合,而是从每个节点获取 :IS_A 关系的程度:

MATCH (o1:Object)-[:CONNECTS_TO]->(o2:Object)
WITH o1, o2, size(()-[:IS_A]->(o1)) AS o1_count, size(()-[:IS_A]->(o2)) AS o2_count 
RETURN o1.name, o1_count, o2.name, o2_count

相关内容

  • 没有找到相关文章

最新更新