Вы можете увидеть, что происходит, если вы просто вернете результаты своего матча:
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