Neo4j中的Union和Count Collections

时间:2015-02-17 08:00:01

标签: collections neo4j cypher union intersection

我的简单数据库包含'术语的节点'和'代码'相互联系。 有两种类型的关系。

'术语之间的关系'和'代码'调用:CODE并且是无向的(或在两个方向上均等地读取)。 术语之间的关系'叫:NT(这意味着狭义的术语)并且是有针对性的。

我想走过所有的条款'从上到下收集所有唯一代码并计算它们。

这是我的疑问:

MATCH (a)-[:NT*]->(b), (a)-[:CODE]-(c), (b)-[:CODE]-(d)
WHERE a.btqty = 0
RETURN a.termid AS termid, a.maxlen AS maxlen, COUNT(DISTINCT c.code) + COUNT(DISTINCT d.code) AS total, COLLECT(DISTINCT c.code) + COLLECT(DISTINCT d.code) AS codes
ORDER BY termid;

这就是我得到的:

termid  maxlen  total   codes
22  2   3   ["S70","S43","S70"]
25  4   9   ["S20","S21","S54","S61","S63","S63","S21","S61","S54"]
26  2   9   ["S99","S98","S29","S13","S13","S20","S29","S14","S15"]
68  5   13  ["S38","S11","S12","S11","S12","S38","S37","S21","S36","S22","S98","S63","S58"]
123 2   3   ["S38","S12","S12"]
154 2   2   ["S58","S58"]
155 4   3   ["S63","S62","S63"]
159 2   2   ["S36","S36"]
...

我需要摆脱集合中的重复项并正确计算它们:

termid  maxlen  total   codes
22  2   2   ["S43","S70"]
25  4   5   ["S20","S21","S54","S61","S63"]
26  2   7   ["S99","S98","S29","S13","S20","S14","S15"]
68  5   10  ["S38","S11","S12","S37","S21","S36","S22","S98","S63","S58"]
123 2   2   ["S38","S12"]
154 2   1   ["S58"]
155 4   2   ["S63","S62"]
159 2   1   ["S36"]
...

我认为这是关于REDUCE功能的应用,但我不知道如何使用它。

感谢您的帮助!

1 个答案:

答案 0 :(得分:4)

你是对的,可以使用REDUCE来解决。在reduce中你需要检查当前元素是否已经存在于累加器中并有条件地修改它:

MATCH (a)-[:NT*]->(b), (a)-[:CODE]-(c), (b)-[:CODE]-(d)
WHERE a.btqty = 0
WITH a.termid AS termid, a.maxlen AS maxlen, 
   REDUCE(uniqueCodes=[], 
         x in COLLECT(DISTINCT c.code) + COLLECT(DISTINCT d.code) |
          CASE WHEN x IN uniqueCodes THEN uniqueCodes ELSE uniqueCodes+x END
   ) AS codes
ORDER BY termid
RETURN termid, maxlen, count(codes) as total, codes