如何检索给定 class 的所有 skos:member(树视图)
How to retrieve all skos:member of a given class (tree view)
我正在处理来自此 SPARQL 端点的数据:http://vocab.getty.edu/sparql。我需要一些关于如何检索维护分层树表示的方面的所有 skos:member(s) 的输入。对于每个 concept/sub-concept 我也会有相关标签过滤 @en , @de , @it , @fr 语言。
- 我已经开始根据方面和相关 skos:member
获取 "core" 层次结构
SELECT DISTINCT ?facet ?concept ?concept_2
?concept_3 ?concept_4
?concept_5
?concept_6
WHERE {{?facet dc:identifier "300264086"} UNION {
OPTIONAL {?facet dc:identifier "300264086";
skos:member ?concept.}} UNION {
OPTIONAL {?facet dc:identifier "300264086";
skos:member/skos:member ?concept_2}} UNION {
OPTIONAL{ ?facet dc:identifier "300264086";
skos:member/ skos:member ?concept_2.
?concept_2 skos:member ?concept_3}} UNION {
OPTIONAL{?facet dc:identifier "300264086";
skos:member/skos:member/skos:member ?concept_3.
?concept_3 skos:member ?concept_4}} UNION {
OPTIONAL{?facet dc:identifier "300264086";
skos:member/skos:member/skos:member/skos:member ?concept_4.
?concept_4 skos:member ?concept_5}} UNION {
OPTIONAL{?facet dc:identifier "300264086";
skos:member/skos:member/skos:member/skos:member/skos:member ?concept_5.
?concept_5 skos:member ?concept_6}}
}
- 然后我向前迈进了一步,还提取了带有按@en、@de、@it、@fr 语言过滤的标签的子概念。
SELECT DISTINCT ?facet ?facet_label_en
?concept ?concept_label_en ?concept_label_de ?concept_label_it ?concept_label_fr
?concept_2 ?concept_2_label_en ?concept_2_label_de ?concept_2_label_it ?concept_2_label_fr
?concept_2a ?concept_2a ?concept_2a_label_en ?concept_2a_label_de ?concept_2a_label_it ?concept_2a_label_fr
?concept_2b ?concept_2b ?concept_2b_label_en ?concept_2b_label_de ?concept_2b_label_it ?concept_2b_label_fr
?concept_3 ?concept_3_label_en
?concept_4 ?concept_4_label_en
?concept_5 ?concept_5_label_en
?concept_6 ?concept_6_label_en
WHERE {{?facet dc:identifier "300264086".
OPTIONAL {{ ?facet xl:prefLabel ?facet_labelEN.?facet_labelEN gvp:term ?facet_label_en.} FILTER langMatches(lang(?facet_label_en), "en").}}
UNION {
OPTIONAL {?facet dc:identifier "300264086";
skos:member ?concept.
OPTIONAL {{ ?concept xl:prefLabel ?concept_labelEN.?concept_labelEN gvp:term ?concept_label_en.} FILTER langMatches(lang(?concept_label_en), "en").}
OPTIONAL {{ ?concept xl:prefLabel ?concept_labelDE.?concept_labelDE gvp:term ?concept_label_de.} FILTER langMatches(lang(?concept_label_de), "de").}
OPTIONAL {{ ?concept xl:prefLabel ?concept_labelIT.?concept_labelIT gvp:term ?concept_label_it.} FILTER langMatches(lang(?concept_label_it), "it").}
OPTIONAL {{ ?concept xl:prefLabel ?concept_labelFR.?concept_labelFR gvp:term ?concept_label_fr.} FILTER langMatches(lang(?concept_label_fr), "fr").}}}
UNION {
OPTIONAL {?facet dc:identifier "300264086";
skos:member/skos:member ?concept_2.
OPTIONAL {{ ?concept_2 xl:prefLabel ?concept_2_labelEN.?concept_2_labelEN gvp:term ?concept_2_label_en.} FILTER langMatches(lang(?concept_2_label_en), "en").}
OPTIONAL {{ ?concept_2 xl:prefLabel ?concept_2_labelDE.?concept_2_labelDE gvp:term ?concept_2_label_de.} FILTER langMatches(lang(?concept_2_label_de), "de").}
OPTIONAL {{ ?concept_2 xl:prefLabel ?concept_2_labelIT.?concept_2_labelIT gvp:term ?concept_2_label_it.} FILTER langMatches(lang(?concept_2_label_it), "it").}
OPTIONAL {{ ?concept_2 xl:prefLabel ?concept_2_labelFR.?concept_2_labelFR gvp:term ?concept_2_label_fr.} FILTER langMatches(lang(?concept_2_label_fr), "fr").}
OPTIONAL {?concept_2 skos:member ?concept_2a.
OPTIONAL {{ ?concept_2a xl:prefLabel ?concept_2a_labelEN.?concept_2a_labelEN gvp:term ?concept_2a_label_en.} FILTER langMatches(lang(?concept_2a_label_en), "en").}
OPTIONAL {{ ?concept_2a xl:prefLabel ?concept_2a_labelDE.?concept_2a_labelDE gvp:term ?concept_2a_label_de.} FILTER langMatches(lang(?concept_2a_label_de), "de").}
OPTIONAL {{ ?concept_2a xl:prefLabel ?concept_2a_labelIT.?concept_2a_labelIT gvp:term ?concept_2a_label_it.} FILTER langMatches(lang(?concept_2a_label_it), "it").}
OPTIONAL {{ ?concept_2a xl:prefLabel ?concept_2a_labelFR.?concept_2a_labelFR gvp:term ?concept_2a_label_fr.} FILTER langMatches(lang(?concept_2a_label_fr), "fr").}
OPTIONAL {?concept_2a skos:member ?concept_2b.
OPTIONAL {{ ?concept_2b xl:prefLabel ?concept_2b_labelEN.?concept_2b_labelEN gvp:term ?concept_2b_label_en.} FILTER langMatches(lang(?concept_2b_label_en), "en").}
OPTIONAL {{ ?concept_2b xl:prefLabel ?concept_2b_labelDE.?concept_2b_labelDE gvp:term ?concept_2b_label_de.} FILTER langMatches(lang(?concept_2b_label_de), "de").}
OPTIONAL {{ ?concept_2b xl:prefLabel ?concept_2b_labelIT.?concept_2b_labelIT gvp:term ?concept_2b_label_it.} FILTER langMatches(lang(?concept_2b_label_it), "it").}
OPTIONAL {{ ?concept_2b xl:prefLabel ?concept_2b_labelFR.?concept_2b_labelFR gvp:term ?concept_2b_label_fr.} FILTER langMatches(lang(?concept_2b_label_fr), "fr").}
OPTIONAL {?concept_2b skos:member ?concept_2c.
OPTIONAL {?concept_2c skos:member ?concept_2d}}}}
}}
UNION {
OPTIONAL{ ?facet dc:identifier "300264086";
skos:member/ skos:member ?concept_2.
?concept_2 skos:member ?concept_3.
OPTIONAL {{ ?concept_3 xl:prefLabel ?concept_3_labelEN.?concept_3_labelEN gvp:term ?concept_3_label_en.} FILTER langMatches(lang(?concept_3_label_en), "en").}}}
UNION {
OPTIONAL{?facet dc:identifier "300264086";
skos:member/skos:member/skos:member ?concept_3.
?concept_3 skos:member ?concept_4.
OPTIONAL {{ ?concept_4 xl:prefLabel ?concept_4_labelEN.?concept_4_labelEN gvp:term ?concept_4_label_en.} FILTER langMatches(lang(?concept_4_label_en), "en").}}}
UNION {
OPTIONAL{?facet dc:identifier "300264086";
skos:member/skos:member/skos:member/skos:member ?concept_4.
?concept_4 skos:member ?concept_5.
OPTIONAL {{ ?concept_5 xl:prefLabel ?concept_5_labelEN.?concept_5_labelEN gvp:term ?concept_5_label_en.} FILTER langMatches(lang(?concept_5_label_en), "en").}}}
UNION {
OPTIONAL{?facet dc:identifier "300264086";
skos:member/skos:member/skos:member/skos:member/skos:member ?concept_5.
?concept_5 skos:member ?concept_6.
OPTIONAL {{ ?concept_6 xl:prefLabel ?concept_6_labelEN.?concept_6_labelEN gvp:term ?concept_6_label_en.} FILTER langMatches(lang(?concept_6_label_en), "en").}}}
}
但是,在 2b 之后添加更多子概念(例如 2c/2d/3/3a/3b...),SPARQL 端点将被阻塞(我不知道这是否是正确的术语)请求(页面无法访问)。
关于如何 improve/optimize/re-write SPARQL 查询有什么建议吗?
谢谢!
另一种方法是使用多个嵌套的 OPTIONAL
块而不是 UNION
。这样,树中节点的路径就是解决方案的一部分。正如@ASKW 指出的那样,这仅适用于 skos:member(或任何其他可传递 属性)的固定深度。
例如建议使用以下内容:
SELECT DISTINCT ?facet ?facet_label_en ?hop1 ?hop2 ?hop3 ?hop4 ?hop5 ?hop6
?concept ?concept_label_en ?concept_label_de ?concept_label_it ?concept_label_fr
WHERE {
?facet dc:identifier "300264086"
OPTIONAL {{ ?facet xl:prefLabel ?facet_labelEN.?facet_labelEN gvp:term ?facet_label_en.} FILTER langMatches(lang(?facet_label_en), "en").}
OPTIONAL {{ ?facet skos:member ?hop1.} union {?facet skos:member ?hop1.
OPTIONAL { {?hop1 skos:member ?hop2.} union {?hop1 skos:member ?hop2
OPTIONAL { {?hop2 skos:member ?hop3} union {?hop2 skos:member ?hop3
OPTIONAL { {?hop3 skos:member ?hop4} union {?hop3 skos:member ?hop4
OPTIONAL { {?hop4 skos:member ?hop5} union {?hop4 skos:member ?hop5
OPTIONAL { ?hop5 skos:member ?hop6 }
}}
}}
}}
}}
}}
bind (COALESCE(?hop6, ?hop5, ?hop4, ?hop3, ?hop2, ?hop1) as ?concept)
OPTIONAL {{ ?concept xl:prefLabel ?concept_labelEN.?concept_labelEN gvp:term ?concept_label_en.} FILTER langMatches(lang(?concept_label_en), "en").}
OPTIONAL {{ ?concept xl:prefLabel ?concept_labelDE.?concept_labelDE gvp:term ?concept_label_de.} FILTER langMatches(lang(?concept_label_de), "de").}
OPTIONAL {{ ?concept xl:prefLabel ?concept_labelIT.?concept_labelIT gvp:term ?concept_label_it.} FILTER langMatches(lang(?concept_label_it), "it").}
OPTIONAL {{ ?concept xl:prefLabel ?concept_labelFR.?concept_labelFR gvp:term ?concept_label_fr.} FILTER langMatches(lang(?concept_label_fr), "fr").}
}
注意在每个嵌套 OPTIONAL
中使用 UNION
,其目的是在结果中也包含中间节点。
HTH
我正在处理来自此 SPARQL 端点的数据:http://vocab.getty.edu/sparql。我需要一些关于如何检索维护分层树表示的方面的所有 skos:member(s) 的输入。对于每个 concept/sub-concept 我也会有相关标签过滤 @en , @de , @it , @fr 语言。
- 我已经开始根据方面和相关 skos:member 获取 "core" 层次结构
SELECT DISTINCT ?facet ?concept ?concept_2
?concept_3 ?concept_4
?concept_5
?concept_6
WHERE {{?facet dc:identifier "300264086"} UNION {
OPTIONAL {?facet dc:identifier "300264086";
skos:member ?concept.}} UNION {
OPTIONAL {?facet dc:identifier "300264086";
skos:member/skos:member ?concept_2}} UNION {
OPTIONAL{ ?facet dc:identifier "300264086";
skos:member/ skos:member ?concept_2.
?concept_2 skos:member ?concept_3}} UNION {
OPTIONAL{?facet dc:identifier "300264086";
skos:member/skos:member/skos:member ?concept_3.
?concept_3 skos:member ?concept_4}} UNION {
OPTIONAL{?facet dc:identifier "300264086";
skos:member/skos:member/skos:member/skos:member ?concept_4.
?concept_4 skos:member ?concept_5}} UNION {
OPTIONAL{?facet dc:identifier "300264086";
skos:member/skos:member/skos:member/skos:member/skos:member ?concept_5.
?concept_5 skos:member ?concept_6}}
}
- 然后我向前迈进了一步,还提取了带有按@en、@de、@it、@fr 语言过滤的标签的子概念。
SELECT DISTINCT ?facet ?facet_label_en
?concept ?concept_label_en ?concept_label_de ?concept_label_it ?concept_label_fr
?concept_2 ?concept_2_label_en ?concept_2_label_de ?concept_2_label_it ?concept_2_label_fr
?concept_2a ?concept_2a ?concept_2a_label_en ?concept_2a_label_de ?concept_2a_label_it ?concept_2a_label_fr
?concept_2b ?concept_2b ?concept_2b_label_en ?concept_2b_label_de ?concept_2b_label_it ?concept_2b_label_fr
?concept_3 ?concept_3_label_en
?concept_4 ?concept_4_label_en
?concept_5 ?concept_5_label_en
?concept_6 ?concept_6_label_en
WHERE {{?facet dc:identifier "300264086".
OPTIONAL {{ ?facet xl:prefLabel ?facet_labelEN.?facet_labelEN gvp:term ?facet_label_en.} FILTER langMatches(lang(?facet_label_en), "en").}}
UNION {
OPTIONAL {?facet dc:identifier "300264086";
skos:member ?concept.
OPTIONAL {{ ?concept xl:prefLabel ?concept_labelEN.?concept_labelEN gvp:term ?concept_label_en.} FILTER langMatches(lang(?concept_label_en), "en").}
OPTIONAL {{ ?concept xl:prefLabel ?concept_labelDE.?concept_labelDE gvp:term ?concept_label_de.} FILTER langMatches(lang(?concept_label_de), "de").}
OPTIONAL {{ ?concept xl:prefLabel ?concept_labelIT.?concept_labelIT gvp:term ?concept_label_it.} FILTER langMatches(lang(?concept_label_it), "it").}
OPTIONAL {{ ?concept xl:prefLabel ?concept_labelFR.?concept_labelFR gvp:term ?concept_label_fr.} FILTER langMatches(lang(?concept_label_fr), "fr").}}}
UNION {
OPTIONAL {?facet dc:identifier "300264086";
skos:member/skos:member ?concept_2.
OPTIONAL {{ ?concept_2 xl:prefLabel ?concept_2_labelEN.?concept_2_labelEN gvp:term ?concept_2_label_en.} FILTER langMatches(lang(?concept_2_label_en), "en").}
OPTIONAL {{ ?concept_2 xl:prefLabel ?concept_2_labelDE.?concept_2_labelDE gvp:term ?concept_2_label_de.} FILTER langMatches(lang(?concept_2_label_de), "de").}
OPTIONAL {{ ?concept_2 xl:prefLabel ?concept_2_labelIT.?concept_2_labelIT gvp:term ?concept_2_label_it.} FILTER langMatches(lang(?concept_2_label_it), "it").}
OPTIONAL {{ ?concept_2 xl:prefLabel ?concept_2_labelFR.?concept_2_labelFR gvp:term ?concept_2_label_fr.} FILTER langMatches(lang(?concept_2_label_fr), "fr").}
OPTIONAL {?concept_2 skos:member ?concept_2a.
OPTIONAL {{ ?concept_2a xl:prefLabel ?concept_2a_labelEN.?concept_2a_labelEN gvp:term ?concept_2a_label_en.} FILTER langMatches(lang(?concept_2a_label_en), "en").}
OPTIONAL {{ ?concept_2a xl:prefLabel ?concept_2a_labelDE.?concept_2a_labelDE gvp:term ?concept_2a_label_de.} FILTER langMatches(lang(?concept_2a_label_de), "de").}
OPTIONAL {{ ?concept_2a xl:prefLabel ?concept_2a_labelIT.?concept_2a_labelIT gvp:term ?concept_2a_label_it.} FILTER langMatches(lang(?concept_2a_label_it), "it").}
OPTIONAL {{ ?concept_2a xl:prefLabel ?concept_2a_labelFR.?concept_2a_labelFR gvp:term ?concept_2a_label_fr.} FILTER langMatches(lang(?concept_2a_label_fr), "fr").}
OPTIONAL {?concept_2a skos:member ?concept_2b.
OPTIONAL {{ ?concept_2b xl:prefLabel ?concept_2b_labelEN.?concept_2b_labelEN gvp:term ?concept_2b_label_en.} FILTER langMatches(lang(?concept_2b_label_en), "en").}
OPTIONAL {{ ?concept_2b xl:prefLabel ?concept_2b_labelDE.?concept_2b_labelDE gvp:term ?concept_2b_label_de.} FILTER langMatches(lang(?concept_2b_label_de), "de").}
OPTIONAL {{ ?concept_2b xl:prefLabel ?concept_2b_labelIT.?concept_2b_labelIT gvp:term ?concept_2b_label_it.} FILTER langMatches(lang(?concept_2b_label_it), "it").}
OPTIONAL {{ ?concept_2b xl:prefLabel ?concept_2b_labelFR.?concept_2b_labelFR gvp:term ?concept_2b_label_fr.} FILTER langMatches(lang(?concept_2b_label_fr), "fr").}
OPTIONAL {?concept_2b skos:member ?concept_2c.
OPTIONAL {?concept_2c skos:member ?concept_2d}}}}
}}
UNION {
OPTIONAL{ ?facet dc:identifier "300264086";
skos:member/ skos:member ?concept_2.
?concept_2 skos:member ?concept_3.
OPTIONAL {{ ?concept_3 xl:prefLabel ?concept_3_labelEN.?concept_3_labelEN gvp:term ?concept_3_label_en.} FILTER langMatches(lang(?concept_3_label_en), "en").}}}
UNION {
OPTIONAL{?facet dc:identifier "300264086";
skos:member/skos:member/skos:member ?concept_3.
?concept_3 skos:member ?concept_4.
OPTIONAL {{ ?concept_4 xl:prefLabel ?concept_4_labelEN.?concept_4_labelEN gvp:term ?concept_4_label_en.} FILTER langMatches(lang(?concept_4_label_en), "en").}}}
UNION {
OPTIONAL{?facet dc:identifier "300264086";
skos:member/skos:member/skos:member/skos:member ?concept_4.
?concept_4 skos:member ?concept_5.
OPTIONAL {{ ?concept_5 xl:prefLabel ?concept_5_labelEN.?concept_5_labelEN gvp:term ?concept_5_label_en.} FILTER langMatches(lang(?concept_5_label_en), "en").}}}
UNION {
OPTIONAL{?facet dc:identifier "300264086";
skos:member/skos:member/skos:member/skos:member/skos:member ?concept_5.
?concept_5 skos:member ?concept_6.
OPTIONAL {{ ?concept_6 xl:prefLabel ?concept_6_labelEN.?concept_6_labelEN gvp:term ?concept_6_label_en.} FILTER langMatches(lang(?concept_6_label_en), "en").}}}
}
但是,在 2b 之后添加更多子概念(例如 2c/2d/3/3a/3b...),SPARQL 端点将被阻塞(我不知道这是否是正确的术语)请求(页面无法访问)。
关于如何 improve/optimize/re-write SPARQL 查询有什么建议吗?
谢谢!
另一种方法是使用多个嵌套的 OPTIONAL
块而不是 UNION
。这样,树中节点的路径就是解决方案的一部分。正如@ASKW 指出的那样,这仅适用于 skos:member(或任何其他可传递 属性)的固定深度。
例如建议使用以下内容:
SELECT DISTINCT ?facet ?facet_label_en ?hop1 ?hop2 ?hop3 ?hop4 ?hop5 ?hop6
?concept ?concept_label_en ?concept_label_de ?concept_label_it ?concept_label_fr
WHERE {
?facet dc:identifier "300264086"
OPTIONAL {{ ?facet xl:prefLabel ?facet_labelEN.?facet_labelEN gvp:term ?facet_label_en.} FILTER langMatches(lang(?facet_label_en), "en").}
OPTIONAL {{ ?facet skos:member ?hop1.} union {?facet skos:member ?hop1.
OPTIONAL { {?hop1 skos:member ?hop2.} union {?hop1 skos:member ?hop2
OPTIONAL { {?hop2 skos:member ?hop3} union {?hop2 skos:member ?hop3
OPTIONAL { {?hop3 skos:member ?hop4} union {?hop3 skos:member ?hop4
OPTIONAL { {?hop4 skos:member ?hop5} union {?hop4 skos:member ?hop5
OPTIONAL { ?hop5 skos:member ?hop6 }
}}
}}
}}
}}
}}
bind (COALESCE(?hop6, ?hop5, ?hop4, ?hop3, ?hop2, ?hop1) as ?concept)
OPTIONAL {{ ?concept xl:prefLabel ?concept_labelEN.?concept_labelEN gvp:term ?concept_label_en.} FILTER langMatches(lang(?concept_label_en), "en").}
OPTIONAL {{ ?concept xl:prefLabel ?concept_labelDE.?concept_labelDE gvp:term ?concept_label_de.} FILTER langMatches(lang(?concept_label_de), "de").}
OPTIONAL {{ ?concept xl:prefLabel ?concept_labelIT.?concept_labelIT gvp:term ?concept_label_it.} FILTER langMatches(lang(?concept_label_it), "it").}
OPTIONAL {{ ?concept xl:prefLabel ?concept_labelFR.?concept_labelFR gvp:term ?concept_label_fr.} FILTER langMatches(lang(?concept_label_fr), "fr").}
}
注意在每个嵌套 OPTIONAL
中使用 UNION
,其目的是在结果中也包含中间节点。
HTH