我想计算和比较两个连接类别的项目数量,但数字似乎不匹配。
假设我有一个图表,例如:
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
。模式中的其余节点是相同的。
对于此处的完整查询,由于有两种可能的模式,其中o1
和o2
相同(这些是非聚合变量(,因此每个计数将为 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