Neo4j 在不同节点上聚合
我拥有的数据模型是:Neo4j 在不同节点上聚合,neo4j,cypher,Neo4j,Cypher,我拥有的数据模型是:(Item)-[:HAS_AN]->(ItemType),两种节点类型都有一个名为ID的字段Items可以与多个ItemTypes相关,在某些情况下,这些ItemTypes可以具有相同的IDs。我试图填充一个结构{ID:…,SameType:…},其中SameType=1,如果一个节点与某个节点具有相同的项类型(ID=1234),则填充0 首先,我得到节点的候选列表qList和源节点的ItemType: MATCH (p:Item{ID:1234})-[:HAS_AN]-&g
(Item)-[:HAS_AN]->(ItemType)
,两种节点类型都有一个名为ID
的字段Item
s可以与多个ItemType
s相关,在某些情况下,这些ItemType
s可以具有相同的ID
s。我试图填充一个结构{ID:…,SameType:…}
,其中SameType=1
,如果一个节点与某个节点具有相同的项类型(ID=1234),则填充0
首先,我得到节点的候选列表qList
和源节点的ItemType
:
MATCH (p:Item{ID:1234})-[:HAS_AN]->(i)
WITH i as pItemType, qList
然后,我通过qList
,将每个节点的ItemType
与pItemType
(即源节点的ItemType
)进行比较:
我遇到的问题是,有些节点有两个ItemType
s,它们具有相同的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
匹配(q:Item),其中q.ID 1234与COLLECT(DISTINCT(q))作为qList
匹配(p:Item{ID:1234})-[:HAS_AN]->(i:ItemType)和i作为pItemType,qList
将qList作为q展开
匹配(q)-[:HAS_AN]->(i:ItemType),q.ID为qID,pItemType,i,
案例一
当pItemType为1时
其他0
以相同的形式结束
返回不同的i、qID、pItemType、SameType
在本例中,
ID=2的Item
有两个与具有相同ID的2个ItemType
节点有一个关系。我只希望返回其中一个。我已尝试简化您的查询。看一看:
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
我试着简化你的问题。看一看:
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
多亏了@Bruno的解决方案,我才能够得到正确的答案。然而,最初的解决方案对我来说并没有立即起作用,原因有二:我需要qList
,因为我后来引用了它,它的DB命中率大约是我问题中查询的4倍。因此,我尝试了一些优化,将DB点击数减少到一半,并在这里为子孙后代分享
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
匹配(q:Item),其中q.ID 1234与COLLECT(DISTINCT(q))作为qList
匹配(p:Item{ID:1234})-[:HAS_AN]->(i:ItemType)和i作为pItemType,qList
将qList作为项目展开
匹配(项目)-[:具有]->(i)
具有
i、 pItemType,
项目ID为qID,
收集({
pItemType:pItemType,
SameType:CASE i.ID
当pItemType.ID为1时,其他0结束
})[0]作为项目
返回i、qID、Item.pItemType作为pItemType、Item.SameType作为SameType
原来运行MATCH(item:item)-[:HAS_AN]->(itemType:itemType)
时添加了一个过滤器
操作,该操作占用的数据库点击量几乎与匹配的一样多。多亏了@Bruno的解决方案,我才能够得到正确的答案。然而,最初的解决方案对我来说并没有立即起作用,原因有二:我需要qList
,因为我后来引用了它,它的DB命中率大约是我问题中查询的4倍。因此,我尝试了一些优化,将DB点击数减少到一半,并在这里为子孙后代分享
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
匹配(q:Item),其中q.ID 1234与COLLECT(DISTINCT(q))作为qList
匹配(p:Item{ID:1234})-[:HAS_AN]->(i:ItemType)和i作为pItemType,qList
将qList作为项目展开
匹配(项目)-[:具有]->(i)
具有
i、 pItemType,
项目ID为qID,
收集({
pItemType:pItemType,
SameType:CASE i.ID
当pItemType.ID为1时,其他0结束
})[0]作为项目
返回i、qID、Item.pItemType作为pItemType、Item.SameType作为SameType
运行MATCH(item:item)-[:HAS_AN]->(itemType:itemType)
时添加了一个过滤器
操作,该操作占用的数据库点击量几乎与匹配的数据库点击量相同。请发布您正在运行的整个查询?谢谢。所以,我想我没有完全理解您的问题,但是尝试将您的RETURN
语句更改为,使用collect({I:I,qID:qID,pItemType:pItemType,SameType:SameType})[0]作为item RETURN item.I,item.qID,item.pItemType,item.SameType
,它只返回一行。我认为它只返回COLLECT()
中的第一个字段?是的,您应该在COLLECT(…)
之前指定一个要分组的字段,比如将I作为I,COLLECT({I:I,qID:qID,pItemType:pItemType,SameType:SameType})[0]作为项返回项。I,item.qID,item.pItemType,item.SameType
。能否与一些示例数据集共享1)a和2)您正在运行的完整查询?请发布您正在运行的整个查询?谢谢。所以,我想我没有完全理解您的问题,但是尝试将您的RETURN
语句更改为,使用collect({I:I,qID:qID,pItemType:pItemType,SameType:SameType})[0]作为item RETURN item.I,item.qID,item.pItemType,item.SameType
,它只返回一行。我认为它只返回COLLECT()
中的第一个字段?是的,您应该在COLLECT(…)
之前指定一个要分组的字段,比如将I作为I,COLLECT({I:I,qID:qID,pItemType:pItemType,SameType:SameType})[0]作为项返回项。I,item.qID,item.pItemType,item.SameType
。您能否与一些示例数据集共享1)a和2)您正在运行的完整查询?谢谢,这确实给了我正确的结果,但它将数据库命中数增加了4倍。你有什么建议吗?我需要以unwindqlist…
的形式进行查询,因为我稍后将再次使用qList
。除此之外,我将您的查询简化为使用MATCH(item)-[:HAS_AN]->(itemType)
和