2017-02-18 2 views
2

Я следующий запрос в Neo4j, который использует UNIONПолучить средние от результата Neo4j накидной

MATCH (u:User {userId:'1'})-[dw:DIRECTOR_WEIGHT]->(d:Person)-[:DIRECTED]->(m:Movie) 
WITH m, avg(dw.weight) AS mean_dw, 0 AS mean_aw, 0 AS mean_gw 
WHERE m.title = 'Bambi' 
RETURN m.title, mean_dw, mean_aw, mean_gw, mean_dw + mean_aw + mean_gw AS total 

UNION 
MATCH (u:User {userId:'1'})-[aw:ACTOR_WEIGHT]->(a:Person)-[:ACTED_IN]->(m:Movie) 
WITH m, 0 AS mean_dw, avg(aw.weight) AS mean_aw, 0 AS mean_gw 
WHERE m.title = 'Bambi' 
RETURN m.title, mean_dw, mean_aw, mean_gw, mean_dw + mean_aw + mean_gw AS total 

UNION 
MATCH (u:User {userId:'1'})-[gw:GENRE_WEIGHT]->(g:Genre)<-[:GENRE]-(m:Movie) 
WITH m, 0 AS mean_dw, 0 AS mean_aw, avg(gw.weight) AS mean_gw 
WHERE m.title = 'Bambi' 
RETURN m.title, mean_dw, mean_aw, mean_gw, mean_dw + mean_aw + mean_gw AS total 

получают следующий результат:

╒═════════╤═══════════════╤════════════════╤═════════════════╤═════════════════╕ 
│"m.title"│"mean_dw"  │"mean_aw"  │"mean_gw"  │"total"   │ 
╞═════════╪═══════════════╪════════════════╪═════════════════╪═════════════════╡ 
│"Bambi" │7.2916666666667│"0"    │"0"    │7.2916666666667 │ 
├─────────┼───────────────┼────────────────┼─────────────────┼─────────────────┤ 
│"Bambi" │"0"   │0.45322110715442│"0"    │0.45322110715442 │ 
├─────────┼───────────────┼────────────────┼─────────────────┼─────────────────┤ 
│"Bambi" │"0"   │"0"    │9.289617486338933│9.289617486338933│ 
└─────────┴───────────────┴────────────────┴─────────────────┴─────────────────┘ 

Моя проблема является «всего» не делает что я намереваюсь сделать, так как мне нужен только один общий фильм (т. е. сумма трех ненулевых весов: 7.29 + 0.45 + 9.28), , но я не могу найти способ использовать этот возвращенный результат дальше. То есть, я хотел бы быть в состоянии сказать что-то вроде

RETURN m.title, sum(total) 

или

RETURN m.title, mean_dw + mean_aw + mean_gw 

после получения союза mean_dw, mean_aw и mean_gw соответственно

ответ

1

Хотя пост-союза обработка в настоящее время не поддерживается Cypher, вы можете обойти это с помощью apoc.cypher.run() в процедурах APOC. Это позволит вам выполнить объединение в рамках прогона и получить объединенный результат, позволяя вам завершить любую оставшуюся обработку, которую вы хотите.

Несмотря на то, что вы просматриваете свои запросы, вы выполняете одинаковые операции в каждом из них, единственное отличие - это отношения, которые следуют в матчах. Существует также некоторая ненужная работа, выполняемая для трех отдельных средних столбцов, поскольку единственное, что вас интересует, - это получение среднего значения веса каждой конкретной связи как среднего, а затем суммирование всех средств.

Это должно позволить нам вырезать некоторые избыточные операции и работать с более узким набором переменных.

Что-то вроде этого:

MATCH (u:User {userId:'1'}), (m:Movie{title:'Bambi'}) 
CALL apoc.cypher.run(" 
MATCH (u)-[dw:DIRECTOR_WEIGHT]->()-[:DIRECTED]->(m) 
RETURN avg(dw.weight) as mean 
UNION ALL 
MATCH (u)-[aw:ACTOR_WEIGHT]->()-[:ACTED_IN]->(m) 
RETURN avg(aw.weight) AS mean 
UNION ALL 
MATCH (u)-[gw:GENRE_WEIGHT]->()<-[:GENRE]-(m) 
RETURN avg(gw.weight) AS mean 
", {u:u, m:m}) YIELD value 
RETURN m.title, SUM(value.mean) as total 

Теперь, все, что сказал, вы не обязательно должны использовать союзы вообще. Вы можете просто использовать подзапросы, связанные с WITH.

MATCH (u:User {userId:'1'}), (m:Movie{title:'Bambi'}) 
MATCH (u)-[dw:DIRECTOR_WEIGHT]->()-[:DIRECTED]->(m) 
WITH u, m, avg(dw.weight) as total 
MATCH (u)-[aw:ACTOR_WEIGHT]->()-[:ACTED_IN]->(m) 
WITH u, m, total + avg(aw.weight) AS total 
MATCH (u)-[gw:GENRE_WEIGHT]->()<-[:GENRE]-(m) 
WITH u, m, total + avg(gw.weight) AS total 
RETURN m.title, total 
+0

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

+0

Нет идей, по образцам данных оба запроса возвращают мне одинаковые результаты. Для первого запроса вы можете захотеть «ВОЗВРАТИТЬ значение», чтобы увидеть каждое из средств до их суммирования, и посмотреть, соответствует ли это ожидаемым. – InverseFalcon