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)