Neo4j Cypher:如何解包路径中的节点以便进行进一步匹配?

9
这个问题是关于之前问题这里的后续。
我有一个包含循环链表的图(这里有一个例子)。链表中的每个节点都指向一个用户。当查询该列表时,我必须使用路径语句,因为该列表是循环的,我不想检索从u:USER节点开始的节点。为了获取感兴趣的节点,我的查询如下:
MATCH path=(nl:NODELINK { linkId:'cc' })-[:LINK*]->(u:USER)
RETURN nodes(path)

一旦我获取了路径,我想对该路径中的节点(NODELINK)进行进一步匹配,类似于以下内容:

MATCH path=(nl:NODELINK { linkId:'cc' })-[:LINK*]->(u:USER)
WITH nodes(path) AS nodeLinks
MATCH nodeLinks-[:PERSONLINK]->persons
RETURN persons

但是如果我尝试,就会出现错误:

Error: Type mismatch: nodeLinks already defined with conflicting type Collection<Node> (expected Node) (line 3, column 7)
"MATCH nodeLinks-[:PERSONLINK]->persons"

如何从路径中拆分出类型为NODELINK的节点,以便对它们进行进一步的MATCH查询?

您能提供一个更具体的例子吗?您试图在数据上回答什么样的问题?我认为答案是,您可能需要以不同的方式对数据进行建模,以反映您试图提出的问题的答案。 - Kenny Bastani
3个回答

5

试试这个...有点hacky,但在没有解开操作之前,它可以工作。

MATCH path=(nl:NODELINK { linkId:'cc' })-[:LINK*]->(u:USER)
WITH [x in nodes(path) | id(x)] AS nodeLinkIds
MATCH (n1:NODELINK)
WHERE id(n1) in nodeLinkIds // this does efficient id lookups for the nodes in the list
MATCH n1-[:PERSONLINK]->persons
RETURN persons

你知道有没有提供取消操作的计划? - Aran Mulholland

4

现在有一个 UNWIND 操作符,所以这应该可以工作:

MATCH path=(nl:NODELINK { linkId:'cc' })-[:LINK*]->(u:USER)
WITH nodes(path) AS x UNWIND x AS nodeLinks
MATCH nodeLinks-[:PERSONLINK]->persons
RETURN persons

我本以为我们可以使用WITH UNWIND nodes(path) AS nodeLinks,但这会在Neo4j 2.2.0-M03中给我一个晦涩的Conversion = '''错误。


那看起来更好,我会去看看。 - Aran Mulholland

0
另一个选项是将期望节点作为行而不是集合返回,然后使用节点的行进行进一步匹配。 要将节点作为行返回,首先指定路径上的节点,然后计算从节点:NODELINK到用户节点的距离,如果距离比起始节点(例如'cc')到结束用户节点的距离更长,则应从结果中排除它。
MATCH path=(:NODELINK { linkId:'cc' })-[:LINK*]->(:USER)
WITH length(path) AS longest
MATCH p=(:NODELINK { linkId:'cc' })-[:LINK*]->(nodeLinks:NODELINK), p1 =(nodeLinks)-[:LINK*]->(:USER)
WITH nodeLinks, length(p1) AS n2u, longest
WHERE n2u <= longest
WITH nodeLinks
MATCH nodeLinks-[:PERSONLINK]->persons
RETURN persons

在控制台中查看结果,http://neo4j-console-20.herokuapp.com/?id=87v0fy


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接