聚合不同节点

时间:2017-11-07 00:19:43

标签: neo4j cypher

我的数据模型是:(Item)-[:HAS_AN]->(ItemType),两个节点类型都有一个名为ID的字段。 Item可以与多个ItemType相关联,在某些情况下,这些ItemType可以具有相同的ID s。我尝试填充结构{ID:..., SameType:...},其中SameType = 1如果某个节点与某个节点具有相同的项目类型(使用ID = 1234),则为qList

首先,我获得节点ItemType的候选列表和源节点MATCH (p:Item{ID:1234})-[:HAS_AN]->(i) WITH i as pItemType, qList

qList

然后,我浏览ItemType,将每个节点pItemTypeItemType(源节点的UNWIND qList as q MATCH (q)-[:HAS_AN]->(i) WITH q.ID as qID, pItemType, i, CASE i WHEN pItemType THEN 1 ELSE 0 END as SameType RETURN DISTINCT i, qID, pItemType, SameType )进行比较:

ItemType

我遇到的问题是某些节点有两个ID具有相同的{ | | { | "ID": 18 | 35258417 | "ID": 71 | 0 } | | } | { | | { | "ID": 18 | 35258417 | "ID": 71 | 0 } | | } | 。这给出了一些条目重复的结果:

DISTINCT

虽然我只想拿一个这样的行,如果存在多个行。 将MATCH (q:Item) WHERE q.ID <> 1234 WITH COLLECT(DISTINCT(q)) as qList MATCH (p:Item{ID:1234})-[:HAS_AN]->(i:ItemType) WITH i as pItemType, qList UNWIND qList as q MATCH (q)-[:HAS_AN]->(i:ItemType) WITH q.ID as qID, pItemType, i, CASE i WHEN pItemType THEN 1 ELSE 0 END as SameType RETURN DISTINCT i, qID, pItemType, SameType 放在我查询的最后部分所在的位置似乎不起作用。过滤掉这些重复项的最佳方法是什么?

更新

以下是一个示例数据子集:http://console.neo4j.org/r/f74pdq

以下是我正在运行的查询

Item

在此示例中,ID = 2 HAS_ANItemType个节点有两个ID个关系,doClick(index) { this.props.click(index); } 节点相同10,000 Nodes x 14B = 140kB 1,000,000 Rels x 33B = 31.5MB 2,010,000 Props x 41B = 78.6MB Total is 110.2MB 。我想只返回其中一个。

2 个答案:

答案 0 :(得分:1)

我试图简化您的查询。看看:

MATCH (:Item {ID : 1234})-[:HAS_AN]->(target:ItemType)

MATCH (item:Item)-[:HAS_AN]->(itemType:ItemType)
WHERE item.ID <> 1234

WITH
    itemType.ID AS i, 
    item.ID AS qID,
    collect({
        pItemType : target,
        SameType : CASE exists((item)-[:HAS_AN]-(target))
                    WHEN true THEN 1 ELSE 0 END
    })[0] as Item

RETURN i, qID, Item.pItemType AS pItemType, Item.SameType AS SameType

诀窍在WITH之后的两行中。此时我按itemType.IDitem.ID分组,而不是(而不是itemTypeitem)。在原始查询中,您使用pItemType进行分组。这不起作用,因为带有ItemType的两个ID = 34是不同的节点,尽管它们具有相同的ID。

控制台的输出:

+-------------------------------------+
| i  | qID | pItemType     | SameType |
+-------------------------------------+
| 31 | 4   | Node[2]{ID:5} | 0        |
| 5  | 3   | Node[2]{ID:5} | 1        |
| 31 | 5   | Node[2]{ID:5} | 0        |
| 45 | 5   | Node[2]{ID:5} | 0        |
| 5  | 1   | Node[2]{ID:5} | 1        |
| 34 | 2   | Node[2]{ID:5} | 0        |
+-------------------------------------+
6 rows
33 ms

答案 1 :(得分:1)

感谢@ Bruno的解决方案,我得到了正确的答案。但是,原始解决方案对我来说无法正常工作有两个原因 - 我需要png(filename="test.png") print( ggplot(df0, aes(x=both, y=value)) + geom_boxplot(aes(fill=both)) + stat_summary(fun.y=mean, geom="point", shape=5, size=4) + geom_text(data=addkw0, aes(x=0, y=0, label=paste0("KW pv = ", formatC(p.adjust, format="e", digits=2))), hjust=0) ) dev.off() ,因为我之后提到它,并且在我的问题中它的查询大约是数据库命中的4倍。所以,我尝试了一些优化,将数据库命中数下降到一半,并在此为后人分享。

qList

结果显示正在运行MATCH (q:Item) WHERE q.ID <> 1234 WITH COLLECT(DISTINCT(q)) as qList MATCH (p:Item{ID:1234})-[:HAS_AN]->(i:ItemType) WITH i as pItemType, qList UNWIND qList as item MATCH (item)-[:HAS_AN]->(i) WITH i, pItemType, item.ID AS qID, collect({ pItemType : pItemType, SameType : CASE i.ID WHEN pItemType.ID THEN 1 ELSE 0 END })[0] as Item RETURN i, qID, Item.pItemType AS pItemType, Item.SameType AS SameType 正在添加MATCH (item:Item)-[:HAS_AN]->(itemType:ItemType)操作,该操作几乎与匹配的数据库命中数一样多。