【问题标题】:Cypher retrieve nodes matching ALL nodes in a setCypher 检索与集合中所有节点匹配的节点
【发布时间】:2018-07-19 18:36:19
【问题描述】:

我正在尝试返回与连接到我的起始节点的集合中的所有节点匹配的节点。作为一个最小的例子,假设我有几个国家的GDP 和Population 的Records。用户执行Query,FILTERS_BY Country=Japan 和DataType = GDP。我想返回GROUPED_BY Japan 和 GROUPED_BY GDP 的所有记录。

最小图可以如下构造:

CREATE
(r1:Record {name: "China GDP"}),
(r2:Record {name: "China Population"}),
(r3:Record {name: "Japan GDP"}),
(r4:Record {name: "Japan Population"}),
(c1:Country {name: "China"}),
(c2:Country {name: "Japan"}),
(s1:DataType {name: "GDP"}),
(s2:DataType {name: "Population"}),
(r1) - [:GROUPED_BY] -> (c1),
(r1) - [:GROUPED_BY] -> (s1),
(r2) - [:GROUPED_BY] -> (c1),
(r2) - [:GROUPED_BY] -> (s2),
(r3) - [:GROUPED_BY] -> (c2),
(r3) - [:GROUPED_BY] -> (s1),
(r4) - [:GROUPED_BY] -> (c2),
(r4) - [:GROUPED_BY] -> (s2),
(q:Query {summary: "Looking for Japan GDP"}),
(q) - [:FILTERED_BY] -> (c2),
(q) - [:FILTERED_BY] -> (s1)
;

这会产生如下图:

我需要编写一个查询来返回 GROUPED_BY 和 Japan 和 GDP 的所有记录(在这种情况下它只是一条记录)。

以下查询返回 GROUPED_BY 日本 OR GDP 的所有记录,但我需要 GROUPED_BY both 的记录。

MATCH (q:Query {summary: "Looking for Japan GDP"}),
(q) - [:FILTERED_BY] -> (filters),
(r:Record) - [:GROUPED_BY] -> (filters)
return r;

产量:

【问题讨论】:

    标签: neo4j cypher


    【解决方案1】:

    我们在performing match intersection 上有一篇 Neo4j 知识库文章,其中提供了一些获得所需结果的方法。

    (还请记住,节点变量可能应该保持单数,因为它们只会匹配每行的单个节点。尝试将复数变量保留到列表中,以避免在查询中混淆。)

    一种可能的方法如下所示:

    MATCH (q:Query {summary: "Looking for Japan GDP"})-[:FILTERED_BY]->(filter)
    WITH filter, size((q)-[:FILTERED_BY]->()) as totalFilterCount
    MATCH (r:Record)-[:GROUPED_BY]->(filter)
    WITH r, count(filter) as matchedFilterCount, totalFilterCount
    WHERE matchedFilterCount = totalFilterCount
    RETURN r
    

    【讨论】:

    • 你为什么使用大小/计数? WITH COLLECT(filter) as filters MATCH (r:Record) WHERE ALL(filter IN filters WHERE (filter)-->(r)) 不是更有效率吗? (至少,对 Cypher Planner 来说不那么令人费解。我不禁想到,传递计数会有细微的错误)
    • 获取该模式的计数应该没有任何问题,它将从节点本身获取关系度,因此成本较低。至于效率测试,您可能希望在具有更多节点和连接的更大版本的图上测试多种方法。
    • @Tezra 您的解决方案没有产生预期的结果。我是否正确实施它? MATCH (q:Query {summary: "Looking for Japan GDP"})-[:FILTERED_BY]->(filter) WITH COLLECT(filter) as filters MATCH (r:Record) WHERE ALL(filter IN filters WHERE (filter)-->(r)) RETURN r
    • filter和r的关系方向是相反的,如果两个节点之间有多个类型,可能需要rel类型。
    • @Sam 对不起,WHERE ALL(filter IN filters WHERE (filter)<-[:GROUPED_BY]-(r)) 更正确。如果 rel 类型是这些节点之间唯一有效的链接类型,则可以省略它,但如果没有它,如果方案发生更改,您也可能会遇到无效匹配。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多