获取neo4j union结果的平均值

时间:2017-02-18 00:08:50

标签: neo4j subquery cypher union

我在neo4j中有以下查询,它使用UNION

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│
└─────────┴───────────────┴────────────────┴─────────────────┴─────────────────┘

我的问题是&#34;总计&#34;不会做我打算做的事,因为我只需要每部电影一个总数(即三个非零重量的总和:7.29 + 0.45 + 9.28), 但我找不到进一步使用此返回结果的方法。即,我希望能够说出类似

的内容
RETURN m.title, sum(total)

RETURN m.title, mean_dw + mean_aw + mean_gw
在分别获得mean_dwmean_awmean_gw的联合后

1 个答案:

答案 0 :(得分:1)

虽然Cypher目前不支持联合后处理,但您可以在APOC程序中使用apoc.cypher.run()解决此问题。这将允许您在运行中执行联合并生成联合结果,从而允许您完成所需的任何剩余处理。

虽然查看您的查询,但您在每个查询中执行相同的操作,唯一的区别是匹配中遵循的关系。对于三个单独的平均列,还有一些不必要的工作正在进行,因为您唯一感兴趣的是将每个特定关系的权重的平均值作为均值,然后将所有方法相加。

这应该允许我们削减一些冗余操作并使用更窄的变量集。

这样的事情:

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