【问题标题】:Cypher returns exponential count result on 'join'Cypher 在“加入”时返​​回指数计数结果
【发布时间】:2015-11-05 16:06:52
【问题描述】:

我正在 Neo4j 上学习 Cypher,但我无法理解如何在 Cypher 中执行有效的“加入”等效操作。

我正在使用标准的矩阵字符示例,并且我已将一些节点添加到名为“Gun”的混合中,其关系为“:GIVEN_TO”。您可以在此处查看带有我的查询结果的控制台:

http://console.neo4j.org/r/rog2hv

我使用的查询是:

MATCH (Neo:Crew { name: 'Neo' })-[:KNOWS*..]->(other:Crew),(other)<-[:GIVEN_TO]-(g:Gun),(Neo)<-[:GIVEN_TO]-(g2:Gun) RETURN count(g2);

我给了 Neo 4 支枪,但是当我执行上述操作时,我得到的计数是“12”。这似乎是因为有 3 个“其他”和 3*4 = 12。所以我得到了一些指数结果。

我的查询应该是什么样子才能从示例中获得正确的计数 ('4')?

编辑: 我没有按照@ceej 的建议直接通过 Guns 进行查询的原因是,在我的实际用例中,我必须如上所述进行遍历。添加DISTINCT 对我的结果没有任何作用。

【问题讨论】:

    标签: database graph neo4j cypher


    【解决方案1】:

    您得到 12 支枪而不是 4 支的原因是您的查询产生了笛卡尔积。这是因为您在没有加入的情况下在同一个匹配语句中请求了项目。 @ceej 正确地指出,如果你想找到 Neo 的枪,你会按照他在第一个查询中的建议进行。

    如果您想获取机组人员及其枪支的列表,那么您可以执行以下操作...

    MATCH (crew:Crew)<-[:GIVEN_TO]-(g:Gun)
    RETURN crew.name, collect(g.name)
    

    找到所有带枪的船员,并返回他们的姓名和给他们的枪。

    如果您想反转它并获取枪支列表以及他们提供给您的相应机组人员,可以执行以下操作...

    MATCH (crew:Crew)<-[:GIVEN_TO]-(g:Gun)
    RETURN g.name, collect(crew.name)
    

    如果您想找到所有了解 Neo 多个级别且获得枪支的船员,您可以编写这样的查询...

    MATCH (crew:Crew)<-[:GIVEN_TO]-(g:Gun)
    WITH crew, g
    MATCH (neo:Crew {name: 'Neo'})-[:KNOWS*0..]->(crew)
    RETURN crew.name, collect(g.name)
    

    这会找到所有获得枪支的船员,然后确定他们中的哪些人拥有通往 Neo 的 :KNOWS 路径。

    【讨论】:

    • 谢谢,这已经接近我的实际用例,当然,我应该更好地布置。现在我剩下的问题是,我将如何获得所有实际的枪支节点,这些节点会提供给了解 Neo 任意级别深度的机组人员?所以认识认识 Neo 的人等等。[:KNOWS*..] 和:是否也可以包括那些工作人员节点?
    • 我设法在这里得到了结果:console.neo4j.org/r/25or9h 但似乎这不是实现这一目标的最佳方法。有什么想法吗?
    • 是的,有更好的方法。我用另一个查询更新了答案,该查询返回知道 Neo 的船员的枪支。
    • 非常感谢戴夫!这正是我所需要的。在我的真实数据库中,它真的非常快(160 毫秒,在超过 300_000 条记录上有 3 个匹配项(一个额外的关系级别))。非常兴奋:)
    【解决方案2】:

    请原谅,但我不清楚为什么您的查询中有初始 MATCH。根据您的解释,您似乎正在尝试通过:GIVEN_TO 关系获取与Neo 链接的:Gun 节点的数量。在这种情况下,您只需要查询的后半部分。这会给你类似的东西

    MATCH (neo:Crew { name: 'Neo' })<-[:GIVEN_TO]-(g:Gun)
    RETURN count(g)
    

    此外,为了确保您只计算不同的 :Gun 节点,您可以将 DISTINCT 添加到 RETURN 语句中。

    MATCH (neo:Crew { name: 'Neo' })<-[:GIVEN_TO]-(g:Gun)
    RETURN count( DISTINCT g )
    

    这在您的情况下可能是不必要的,但当您匹配的模式可以通过不同的遍历到达同一节点时会很有帮助。

    我是否误解了您的要求?

    【讨论】:

    • 实际上我并不想数枪数。我正在尝试获取所有机组人员及其枪支的结果集。我通过计数询问并通过 Neo 认识的人进行计数的原因是,尽管通过已知的联系人,我仍想获得正确的计数。我会尝试在问题中更清楚地说明这一点。
    猜你喜欢
    • 2023-03-26
    • 1970-01-01
    • 2013-01-29
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    • 2014-11-07
    • 1970-01-01
    • 2012-07-26
    相关资源
    最近更新 更多