apoc.path.expandConfig() 提取(主语)-[宾语]->(谓语)三元组

apoc.path.expandConfig() extract (subject)-[object]->(predicate) triplet

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

(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 列表?

这里的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()) 将提供具有交替节点-关系-节点-关系元素的路径的列表形式,但您想使用三元组,所以我们需要对该列表进行一些操作并通过索引选择子列表以获取路径中所有三元组的列表。然后我们可以提取我们想要的三元组属性,然后应用字符串格式。

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

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