简体   繁体   English

Neo4j Cypher:为什么0长度路径不匹配?

[英]Neo4j Cypher: why does this 0-length path not MATCH?

Imagine a simple Twitter scenario: 想象一个简单的Twitter场景:

  • Alice tweets something (id 1). 爱丽丝(Alice)鸣叫一些东西(ID 1)。
  • Bob replies with something (id 2). 鲍勃回答某事(编号2)。

So eg in Cypher: 因此,例如在Cypher中:

CREATE
    (parent:Tweet {id: 1}) -[:AUTHOR]-> (:User {name: 'Alice'}),
    (child:Tweet {id: 2}) -[:AUTHOR]-> (:User {name: 'Bob'}),
    (child) -[:IN_REPLY_TO]-> (parent)

I want to write a query that, for any tweet, returns the tweet and the author alongside the very first/original tweet and author in that conversation. 我想编写一个查询,对于任何推文,都返回该推文和作者以及该对话中的第一个/原始推文和作者。

So for tweet 1, it should return 1, Alice, 1, Alice , but for tweet 2, it should return 2, Bob, 1, Alice . 因此,对于推文1,它应该返回1, Alice, 1, Alice ,但是对于推文2,它应该返回2, Bob, 1, Alice

Here's my query: 这是我的查询:

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

(I know I could achieve this with an OPTIONAL MATCH , but achieving this with a potential zero-length path instead would be helpful to me for other reasons.) (我知道我可以通过OPTIONAL MATCH实现此目的,但是出于其他原因,可以通过潜在的零长度路径实现这一点。)

This works great on tweet 2, but doesn't return any results for tweet 1. I'm at a loss for why, but I'm sure I'm missing something obvious. 这在tweet 2上效果很好,但不会为tweet 1返回任何结果。我不知道为什么,但是我确定我缺少明显的东西。 Any ideas? 有任何想法吗?

(When I say the query out loud, it seems fine. Tweet 2 has an author; it with a zero-length reply chain, it is the original; it as the original still has an author; and it as the original is not in reply to any other tweet.) (当我大声说出查询时,它看起来还不错。Tweet 2有一个作者;它的回复链长度为零,它是原始的;它仍然是原始的,仍然是作者;并且由于原始的不在回复其他任何推文。)

Here's a live console to play with: 这是一个可玩的现场控制台:

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

Thanks! 谢谢!

You're encountering the "single relationship traversal" rule. 您遇到了“单关系遍历”规则。 Within a single MATCH , you can only traverse any relationship once. 在单个MATCH ,您只能遍历任何关系一次。 This is very helpful in the 90% case, to prevent matches that loop or track back over relationships. 在90%的情况下,这对于防止匹配循环或追溯关系非常有用。

However, in your case this means that the second part of your match cannot use the same relationship used in the first part. 但是,根据您的情况,这意味着比赛的第二部分不能使用第一部分中使用的相同关系。 Hence it's not matching. 因此,它不匹配。

The solution is simple - use a separate MATCH clause: 解决方案很简单-使用单独的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM