我想计算并比较两个相关类别的项目数,但这些数字似乎不匹配。
假设我有一个图表,如:
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)
Object1连接到Object2,同时Object1与Item1关联,Object2与Item2和Item3关联。
然后我想计算每个对象的项目数:
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
有人能告诉我我做错了吗?
答案 0 :(得分:1)
如果您只是返回匹配结果,您可以看到正在发生的事情:
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