树的折叠分支的 SPARQL 查询(总结拓扑)

SPARQL query for collapsing branches of a tree (summarizing topology)

假设我们有相同的 this 问题树

ADEH是属于[=47=的'special'节点] :Special。这是树定义

@prefix : <http://example.org#> .

:orgA :hasSuborganization :orgB, :orgC, :orgD.
:orgB :hasSuborganization :orgE, :orgF.
:orgE :hasSuborganization :orgG.
:orgG :hasSuborganization :orgH.
:orgA a :Special .
:orgD a :Special .
:orgE a :Special .
:orgH a :Special .

我想要获得与起始树相同的树,但只有 special 节点。一种起始拓扑的总结。例如,预期输出:

  A
 _|_
|   |
E   D
|
H

我想通过 SPARQL 查询获得它。我的出发点:

@prefix : <http://example.org#> .

select ?node ?node2 (count(?mid) as ?distance) where {
    ?node :hasSuborganization* ?mid .
    ?mid :hasSuborganization+ ?node2 .
    ?node2 a :Special .
    {
        select * where { 
            <http://example.org#orgA> :hasSuborganization* ?node .
            ?node a :Special .
        }
    }
} group by ?node ?node2

这样我就得到了树中每对特殊节点的距离。

如何只过滤超级-子关系(即 A-DA-EE-H)?我相信在我的结果集中过滤具有最小值的行就足够了。实际上,如果一个 :Special 节点有 :Special 个处于不同高度的后代(例如,距离(A-D)= 1,距离(A-E)= 2)。

可能我需要一些不同的东西。

根据评论中的 AKSW 线索进行推理,可能的解决方案是:

@prefix : <http://example.org#> .

select * where {
    ?node :hasSuborganization+ ?end .
    ?end  a :Special .
    FILTER NOT EXISTS {
        ?node :hasSuborganization+ ?mid .
        ?mid :hasSuborganization+ ?end .
        ?mid a :Special .
    }
    {
        select * where { 
            :orgA :hasSuborganization* ?node .
            ?node a :Special .
        }
    }
}

解释:

最内层查询returns所有:Special个节点来自一个根节点(即:orgA)。

select * where { 
    :orgA :hasSuborganization* ?node .
    ?node a :Special .
}

然后,外部查询选择所有可能的 ?node :hasSuborganization+ ?end 模式。例如,对于 ?node = :orgA,我们得到:A-DA-EE-H.

最后,外部查询使用 :Special 中间节点(即 ?mid)过滤掉模式

FILTER NOT EXISTS {
    ?node :hasSuborganization+ ?mid .
    ?mid :hasSuborganization+ ?end .
    ?mid a :Special .
}

最终结果集是 <?node?end> 对夫妇的集合,用于构建此汇总树:

  A
 _|_
|   |
E   D
|
H

这个查询工作正常,即使当树变大时它不能很好地扩展。优化或不同的策略是可能的。