[英]Neo4j Cypher: why does this 0-length path not MATCH?
想象一个简单的Twitter场景:
因此,例如在Cypher中:
CREATE
(parent:Tweet {id: 1}) -[:AUTHOR]-> (:User {name: 'Alice'}),
(child:Tweet {id: 2}) -[:AUTHOR]-> (:User {name: 'Bob'}),
(child) -[:IN_REPLY_TO]-> (parent)
我想编写一个查询,对于任何推文,都返回该推文和作者以及该对话中的第一个/原始推文和作者。
因此,对于推文1,它应该返回1, Alice, 1, Alice
,但是对于推文2,它应该返回2, Bob, 1, Alice
。
这是我的查询:
MATCH
(tweet:Tweet {id: {id}}) -[:AUTHOR]-> (author:User),
(tweet) -[:IN_REPLY_TO*0..]-> (original:Tweet) -[:AUTHOR]-> (originalAuthor:User)
WHERE NOT(original -[:IN_REPLY_TO]-> ())
RETURN tweet, author, original, originalAuthor
(我知道我可以通过OPTIONAL MATCH
实现此目的,但是出于其他原因,可以通过潜在的零长度路径实现这一点。)
这在tweet 2上效果很好,但不会为tweet 1返回任何结果。我不知道为什么,但是我确定我缺少明显的东西。 有任何想法吗?
(当我大声说出查询时,它看起来还不错。Tweet 2有一个作者;它的回复链长度为零,它是原始的;它仍然是原始的,仍然是作者;并且由于原始的不在回复其他任何推文。)
这是一个可玩的现场控制台:
http://console.neo4j.org/r/d719lz
谢谢!
您遇到了“单关系遍历”规则。 在单个MATCH
,您只能遍历任何关系一次。 在90%的情况下,这对于防止匹配循环或追溯关系非常有用。
但是,根据您的情况,这意味着比赛的第二部分不能使用第一部分中使用的相同关系。 因此,它不匹配。
解决方案很简单-使用单独的MATCH
子句:
MATCH (tweet:Tweet {id: {id}}) -[:AUTHOR]-> (author:User),
MATCH (tweet) -[:IN_REPLY_TO*0..]-> (original:Tweet) -[:AUTHOR]-> (originalAuthor:User)
WHERE NOT(original -[:IN_REPLY_TO]-> ())
RETURN tweet, author, original, originalAuthor
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.