apoc.path.expandConfig()提取(主题)-[对象]->(谓词)三元组

时间:2019-01-25 10:58:31

标签: neo4j cypher neo4j-apoc

我正在尝试编写一个密码查询,当给定一个特定的开始并且一个固定的终止节点时,密码查询将继续并扩展路径并以以下格式提取节点和关系。

(node1)-[relation]->[node2],即(subject)-[object]->(predicate)三元组

这是我正在尝试的密码查询:

MATCH (e1: Location { name: 'Pune' }), (e2: Location { name: 'Bangalore' })
CALL apoc.path.expandConfig(e1, { terminatorNodes: [e2], limit: 2  }) YIELD path
WITH [relation in relationships(path) | type(relation)] as rel, nodes(path) as nodes
RETURN { Relations: rel, Nodes: nodes } as results

我尝试使用列表推导将其分组为格式,但是无法执行此操作,您可以指出我正在犯的任何明显错误。


更新:

我需要使用它们之间的关系进行多跳路径,是否有可能使用nodes列表?

1 个答案:

答案 0 :(得分:1)

这里的limit: 2意味着您将获得2个结果路径,而不是路径的长度为2。您可以使用minLevelmaxLevel配置属性来限制要扩展的数量表演。对于单个扩展(开始节点,1个关系,结束节点),可以将它们都设置为1。

关于格式化此输出,最简单的方法是安装APOC Procedures并使用apoc.text.format()函数(此方法与sprintf()java方法一起使用)。

例如:

MATCH (e1: Location { name: 'Pune' }), (e2: Location { name: 'Bangalore' })
CALL apoc.path.expandConfig(e1, { terminatorNodes: [e2], minLevel: 1, maxLevel:1  }) YIELD path
WITH e1, e2, [relation in relationships(path) | type(relation)][0] as rel
RETURN apoc.text.format('(%s)-[%s]->(%s)',[e1.name, rel, e2.name])

也就是说,我不确定这里是否需要路径扩展器。除非有特殊情况,否则Cypher应该足够:

MATCH (e1: Location { name: 'Pune' }), (e2: Location { name: 'Bangalore' })
MATCH (e1)-[rel]->(e)
where e = e2 // to force a 2-node index lookup and hash join
WITH e1, e2, type(rel) as rel
RETURN apoc.text.format('(%s)-[%s]->(%s)',[e1.name, rel, e2.name])

编辑

好的,因此您似乎需要使用它来查找多跳的路径,对路径的一些限制以及将路径表示为三元组。

不幸的是,尽管路径以这种三重格式显示(显示每个元素的所有属性),但路径不是列表,我们无法将它们作为列表进行处理。

有一个APOC函数(apoc.path.elements()),它将提供具有交替的node-relationship-node-relationship元素的路径的列表形式,但是您要使用三元组,因此我们需要这样做对该列表进行一些操作,并通过索引选择子列表,以获取路径中所有三元组的列表。然后,我们可以提取三元组所需的属性,然后应用字符串格式。

假设我们只是在扩展外向关系(否则,我们需要付出更多努力才能在所有三元组中正确表示正确的方向)。

MATCH (e1: Location { name: 'Pune' }), (e2: Location { name: 'Bangalore' })
CALL apoc.path.expandConfig(e1, { terminatorNodes: [e2], relationshipFilter:'>', limit:2}) YIELD path
WITH apoc.path.elements(path) as pathElements
WITH [idx in range(0, size(pathElements) - 1) | CASE WHEN idx % 2 = 0 THEN pathElements[idx].name ELSE type(pathElements[idx]) END] as pathElements
WITH [idx in range(0, size(pathElements) - 2, 2) | pathElements[idx..idx+3]] as triplets
WITH [triplet in triplets | apoc.text.format('(%s)-[%s]->(%s)', triplet)] as tripletsText
RETURN tripletsText