【问题标题】:Query nodes from multiple specific paths in cypher从密码中的多个特定路径查询节点
【发布时间】:2014-07-14 14:31:36
【问题描述】:

我正在玩 cypher,我正在做一些简单的聚合。

MATCH (p:Person)-[:HAS_CAR]->(n:Car)
RETURN n, count(p)

MATCH (p:Person)-[:HAS_APARTMENT]->(n:Apartment)
RETURN n, count(p)

MATCH (p:Person)-[:HAS_HOUSE]->(n:House)
RETURN n, count(p)

问题是我必须对数据库进行 3 次访问才能将所有这些结果汇总在一起。问题在于这些查询是更大链中的最后一个MATCH 语句。像这样:

MATCH (:City { Id: 10})<-[:LIVES_IN]-(p:Person)
WITH p
MATCH ...
WITH p
MATCH ...
WITH p
MATCH ...
WITH p
MATCH ...
WITH p
MATCH p-[:HAS_CAR]->(n:Car)
RETURN n, count(p)

在所有这些MATCH ... WITH 语句之后,只有几个人节点匹配,所以查询的最后部分非常快,但初始部分不是。我不禁认为这可以改进,因为所有三个查询共享很多语句。

我想出了这个:

...
MATCH p-[:HAS_CAR|HAS_APARTMENT|HAS_HOUSE]->(n)
RETURN n, labels(n), count(p)

我可以使用它。但是,如果我想混合这样的东西怎么办:

MATCH p-[:KNOWS]->(:Person)-[:HAS_BIKE]->(n:Bike)
RETURN n, count(p)

甚至:

MATCH p-[:KNOWS]->(:Person)-[:HAS_BIKE|HAS_BOAT]->(n)
RETURN n, labels(n), count(p)

所有这些都可以在一个查询中完成吗?如何完成?

【问题讨论】:

    标签: neo4j cypher


    【解决方案1】:

    有时您需要使用集合而不是行来将聚合查询合并在一起并传递它们。这种策略可能会有所帮助……例如:

    MATCH (p:Person)-[:HAS_CAR]->(car:Car)
    WITH car, count(p) carCount
    WITH collect({car:car, count:carCount}) as carCounts
    MATCH (p:Person)-[:HAS_APARTMENT]->(n:Apartment)
    WITH n, count(p) as apartmentCount, carCounts
    RETURN collect({apartment:n, count:apartmentCount}) as apartmentCounts, carCounts
    

    更新(参见 cmets)——这让您可以传递过滤器的结果并快速查找 id 以再次找到它们:

    MATCH (p:Person)
    WHERE p.name = "John" // or whatever else you need to filter on
    WITH collect(id(p)) as pids
    MATCH (p)-[:HAS_CAR]->(car:Car)
    WHERE id(p) IN pids
    WITH car, count(p) carCount, pids
    WITH collect({car:car, count:carCount}) as carCounts, pids
    MATCH (p)-[:HAS_APARTMENT]->(n:Apartment)
    WHERE id(p) IN pids
    WITH n, count(p) as apartmentCount, carCounts
    RETURN collect({apartment:n, count:apartmentCount}) as apartmentCounts, carCounts
    

    【讨论】:

    • 因为您没有在WITH car, count(p) as carCount 中传递p,所以语句MATCH (p:Person)-[:HAS_APARTMENT]-&gt;(n:Apartment) 不尊重先前的过滤链并匹配所有 个人节点。如果您添加 p 之类的 WITH p, car, count(p) as carCount,则 count(p) 聚合不正确。有没有办法解决这个问题?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-05
    • 2023-01-28
    • 1970-01-01
    • 2014-01-09
    • 1970-01-01
    相关资源
    最近更新 更多