Neo4j: Подсчет предметов, принадлежащих к двум различным категориям - PullRequest
0 голосов
/ 06 июня 2018

Я хочу посчитать и сравнить количество элементов в двух связанных категориях, но цифры не совпадают.

Допустим, у меня есть график, такой как:

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

Может кто-нибудь сказать мне, что я делаю неправильно?

1 Ответ

0 голосов
/ 06 июня 2018

Вы можете увидеть, что происходит, если вы просто вернете результаты своего матча:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...