【问题标题】:apoc.path.expandConfig() extract (subject)-[object]->(predicate) tripletapoc.path.expandConfig() extract (subject)-[object]->(predicate) 三元组
【发布时间】:2019-01-25 10:58:30
【问题描述】:

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

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

【问题讨论】:

    标签: neo4j cypher neo4j-apoc


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

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

    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
    

    【讨论】:

    • 另外我想把结果投影成(node1)-[relation]->(node2)的格式,怎么做?
    • [relation in relationships(path) | type(relation)][0] 这是硬编码每次都打印关系列表的第一个索引?
    • 是的。你说你只想要三元组,所以这只是一个单跳,所以每条路径的长度都是 1,只有一个关系。或者您是否在寻找可变长度路径并像这样显示路径中的所有三元组?
    • 我认为您需要在这里非常清楚:您是否期望仅由单跳(三元组)组成的路径,并且您不知道其中有多少存在,或者您是否正在寻找一些未知长度的路径,并且您想将每条路径的表示分解为多个三元组?
    • 这很公平。这种更复杂的情况可能会被编码为 APOC 中的一个单独函数(类似于apoc.path.asCypherTriples(path),但它需要一种方法来指定从相关节点中提取哪些属性。
    猜你喜欢
    • 2016-02-15
    • 2014-06-04
    • 2022-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-07
    • 1970-01-01
    • 2020-12-22
    相关资源
    最近更新 更多