首页 > 解决方案 > SPARQL 查询从给定的根路径走路径

问题描述

什么 SPARQL 语法允许指定根节点,同时将该节点外的关系路径消耗到给定的限制。

例如

Graph1是身体部位的解剖图。

k_anatomy:K403 a k:Anatomy ;
    rdfs:label "Finger" ;
    k_anatomy:has_parent k_anatomy:K393 .

k_anatomy:K393 a k:Anatomy ;
    rdfs:label "Hand" ;
    k_anatomy:has_parent k_anatomy:K370 .

k_anatomy:K370 a k:Anatomy ;
    rdfs:label "Free Upper Limb" ;
    k_anatomy:has_parent k_anatomy:K359 .


k_anatomy:K359 a k:Anatomy ;
    rdfs:label "Upper Limb" ;
    k_anatomy:has_parent k_anatomy:K358 .


k_anatomy:K358 a k:Anatomy ;
    rdfs:label "Limb" ;
    k_anatomy:has_parent k_anatomy:K2 .


k_anatomy:K2 a k:Anatomy ;
    rdfs:label "Body_by_region" ;
    k_anatomy:has_parent k_anatomy:K1 .


k_anatomy:K1 a k:Anatomy ;
    rdfs:label "Body" ;
    k_anatomy:has_parent k_anatomy:K0 .

让(rdfs:label "Finger")root成为k_anatomy:K403 (rdfs:label "Finger")

问题

k_anatomy:K403给定 IRI =和关系的SPARQL 查询k_anatomy:has_parent将构成以下结果:

| BodyPart          | PartOf            | 
-----------------------------------------
| Finger            | Hand              |
| Hand              | Free Upper Limb   |
| Free Upper Limb   | Upper Limb        |
| Upper Limb        | Limb              |
| Limb              | Body_by_region    |
| Body_by_region    | Body              |

标签: sparqlrdfsemantic-web

解决方案


无需为此指定根节点。这个查询:

SELECT ?BodyPart ?PartOf
WHERE { 
    ?S rdfs:label ?BodyPart;
       k_anatomy:has_parent [ rdfs:label ?PartOf ]. 
} 

会成功的。

我只是在本地 RDF4J 控制台上运行它。输出:

Evaluating SPARQL query...
+-------------------------------------+-------------------------------------+
| BodyPart                            | PartOf                              |
+-------------------------------------+-------------------------------------+
| "Finger"                            | "Hand"                              |
| "Hand"                              | "Free Upper Limb"                   |
| "Free Upper Limb"                   | "Upper Limb"                        |
| "Upper Limb"                        | "Limb"                              |
| "Limb"                              | "Body_by_region"                    |
| "Body_by_region"                    | "Body"                              |
+-------------------------------------+-------------------------------------+
6 result(s) (36 ms)

一个警告:这里解决方案的顺序是任意的,它恰好与您的预期结果很好地对齐,因为在这种情况下,RDF4J 引擎只是按照它们在原始文件中出现的顺序将结果吐回 - 但这不能保证每次都会发生,当然不会跨三元存储实现。

如果您的商店包含比您提供的输入文件更多的数据,则更新,然后要获得您想要的结果,您需要稍微复杂一点的查询。具体来说,您将需要使用所谓的“属性路径”表达式。这允许您指定您想要从某个点开始的任意长度的路径。像这样:

SELECT ?BodyPart ?PartOf
WHERE { 
     k_anatomy:K393 k_anatomy:has_parent* ?S .
     ?S rdfs:label ?BodyPart;
        k_anatomy:has_parent [ rdfs:label ?PartOf ].  
} 

您仍然希望身体部位与他们的父母(所以查询的最后一部分与原始查询相同),但现在我们通过属性路径添加一个额外的约束,说值?S必须是,通过长度路径零个或多个,K393通过has_parent关系链接到。

结果:

Evaluating SPARQL query...
+-------------------------------------+-------------------------------------+
| BodyPart                            | PartOf                              |
+-------------------------------------+-------------------------------------+
| "Hand"                              | "Free Upper Limb"                   |
| "Free Upper Limb"                   | "Upper Limb"                        |
| "Upper Limb"                        | "Limb"                              |
| "Limb"                              | "Body_by_region"                    |
| "Body_by_region"                    | "Body"                              |
+-------------------------------------+-------------------------------------+
5 result(s) (6 ms)

正如您所看到的,这并没有像预期的那样列出“Finger” - 当然,这只有在has_parent关系不形成循环时才能正常工作。


推荐阅读