2017-01-10 3 views
3

Я пытался создать объединение двух необязательных совпадений (как показано ниже), но вместо объединения я получаю пересечение двух. Как мне изменить этот запрос, чтобы получить необходимый союз?Cypher for neo4j

optional match (a:PA)-[r2:network*2]-(b:PA) where a.last_name='smith'  
And Not (a:PA)-[:network]-(b:PA) 
optional match (a:PA)-[r3:network*3]-(b:PA) where a.last_name='smith' 
And Not (a:PA)-[:network]-(b:PA) 
return b.first_name, count(r2), count(r3) 

Эта база данные графа должна имитировать социальные network.Through первого дополнительный матч я попытался найти второе соединение степени в сети пользователя (кузнец) и отсчет времени они появляются как 2-ой степени соединение в его сети. Второй матч делает то же самое для соединений третьей степени.

Но запрос возвращает пересечение 2 необязательных совпадений вместо их объединения, т. Е. Я получаю подсчет только тех имен, которые могут отображаться как как 2 степени, так и 3-градусное соединение по отношению к пользователя (кузнец).

Вместо этого я хотел бы получить имя всех соединений второй степени и третьей степени вместе со счетами. Как изменить этот запрос, чтобы получить требуемые результаты?

ответ

3

Я думаю, в вашем случае объединение не требуется:

match path = (a:PA {last_name: 'smith'})-[r2:network*2..3]-(b:PA) 
where not (a:PA)-[:network]-(b:PA) 
with b.first_name as name, 
    CASE WHEN length(path) = 2 THEN 1 ELSE 0 END as deg2 
    CASE WHEN length(path) = 3 THEN 1 ELSE 0 END as deg3 
RETURN name, sum(deg2), sum(deg3) 
0

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

  1. матч кузнец
  2. необязательно соответствует 2-й степени кузнеца PA
  3. собрать 2-й соединения степени
  4. необязательно соответствует 3-й степени кузнеца PA
  5. собрать 3ND соединения степени
  6. вернуть коллекции 2-й и 3-й степени PA вместе с размером каждого из них.

Вот предлагаемый запрос

match (a:PA) 
where a.last_name='smith'  
with a 
optional match (a)-[r2:network*2]-(b:PA) 
where Not (a)-[:network]-(b) 
with a, collect(b.first_name) as 2_deg 
optional match (a)-[r3:network*3]-(b:PA) 
where Not (a)-[:network]-(b) 
return 2_deg, collect(b.first_name) as 3_deg, size(2_deg) as num_2_deg, size(3_deg) as num_3_deg 

Если вы сделали действительно хотите объединение двух различных запросов, которые нужно оператор возврата для каждой половины, соответствующие столбцы и UNION ALL. Вот образец, но я не думаю, что это то, что вы ищете.

optional match (a:PA)-[r2:network*2]-(b:PA) 
where a.last_name='smith'  
And Not (a:PA)-[:network]-(b:PA) 
return b.first_name, count(r2) as num 
UNION ALL 
optional match (a:PA)-[r3:network*3]-(b:PA) 
where a.last_name='smith' 
And Not (a:PA)-[:network]-(b:PA) 
return b.first_name, count(r3) as num