Neo4j Cypher:如何从路径中解压缩节点以允许进一步匹配?

时间:2014-03-04 22:54:23

标签: neo4j cypher

这个问题是问题here

的后续问题

我有一个包含循环链表的图表。 (see here for an example)链接列表中的每个节点都指向一个用户。查询列表时,我必须使用路径语句,因为列表是循环的,我不想从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查询?

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:3)

现在有一个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 = '''错误。

答案 2 :(得分:0)

另一种选择是将所需节点作为行而不是集合返回,然后再与节点行进行匹配。 要将节点作为行返回,首先指定路径上的节点,然后计算距节点的距离:NODELINK到节点User,如果距离长于从起始节点(例如'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