Cypher在' join'上返回指数计数结果

时间:2015-11-05 16:06:53

标签: database graph neo4j cypher

我在Neo4j上学习Cypher,我在理解如何有效地加入'相当于Cypher。

我正在使用标准的Matrix字符示例,我在混合中添加了一些名为“Gun' 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;&#39; 12。这似乎是这种情况,因为有3个其他人&#39;并且3 * 4 = 12.所以我得到一些指数结果。

我的查询应该如何从示例中获得正确的计数(&#39; 4&#39;)?

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

2 个答案:

答案 0 :(得分:4)

你获得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)

找到所有给予枪支的船员,然后确定他们中哪一个有:KNOWS路径到Neo。

答案 1 :(得分:2)

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

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 )

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

我误解了你的要求吗?