SPARQL - 递归查询以获取术语及其所有多级子级

时间:2016-08-03 09:20:49

标签: recursion sparql

我为这个词库写了一个查询: http://vocabs.ceh.ac.uk/evn/tbl/envthes.evn#http%3A%2F%2Fvocabs.lter-europe.net%2FEnvThes%2F10000

Sparql端点在这里: http://vocabs.ceh.ac.uk/evn/tbl/swp?_viewClass=endpoint:HomePage 只需选择“urn:x-evn-pub:envthes”作为默认图表。

它返回在术语“度量”(http://vocabs.lter-europe.net/EnvThes/10004)下排序的每个术语。它可以按照需要工作,但问题是既不优雅也不容易这样写。

因此,我正在寻找更好的方法来编写以下查询:

select distinct ?concept (str(?prefLab) as ?label) (str(?altlab) as ?code)
(str(?p) as ?parent) (str(?pl) as ?parlab) ("EnvThes" as ?source)

WHERE {
 ?concept <http://www.w3.org/2004/02/skos/core#broader> ?level2.
 ?concept <http://www.w3.org/2004/02/skos/core#prefLabel> ?prefLab.
 OPTIONAL {?concept <http://www.w3.org/2004/02/skos/core#altLabel> ?altlab.
  FILTER (lang(?altlab)='en').
 }.

 OPTIONAL {?concept <http://www.w3.org/2004/02/skos/core#broader> ?p.
 ?p <http://www.w3.org/2004/02/skos/core#prefLabel> ?pl}
 OPTIONAL
 {?level2 <http://www.w3.org/2004/02/skos/core#broader> ?level3.
 OPTIONAL
 {?level3 <http://www.w3.org/2004/02/skos/core#broader> ?level4.
 OPTIONAL
 {?level4 <http://www.w3.org/2004/02/skos/core#broader> ?level5.
 OPTIONAL
 {?level5 <http://www.w3.org/2004/02/skos/core#broader> ?level6.
 OPTIONAL
 {?level6 <http://www.w3.org/2004/02/skos/core#broader> ?level7.
 OPTIONAL
 {?level7 <http://www.w3.org/2004/02/skos/core#broader> ?level8.
 OPTIONAL
 {?level8 <http://www.w3.org/2004/02/skos/core#broader> ?level9.
 OPTIONAL
 {?level9 <http://www.w3.org/2004/02/skos/core#broader> ?level10.
 }.}.}.}.}.}.}.}.

 FILTER(
  ?level10 = <http://vocabs.lter-europe.net/EnvThes/10004> || 
  ?level9 = <http://vocabs.lter-europe.net/EnvThes/10004> ||
  ?level8 = <http://vocabs.lter-europe.net/EnvThes/10004> ||
  ?level7 = <http://vocabs.lter-europe.net/EnvThes/10004> ||
  ?level6 = <http://vocabs.lter-europe.net/EnvThes/10004> ||
  ?level5 = <http://vocabs.lter-europe.net/EnvThes/10004> ||
  ?level4 = <http://vocabs.lter-europe.net/EnvThes/10004> ||
  ?level3 = <http://vocabs.lter-europe.net/EnvThes/10004> ||
  ?level2 = <http://vocabs.lter-europe.net/EnvThes/10004>).
 FILTER(lang(?prefLab) = 'en'). 
}

有没有办法让这个递归?我仍然是Sparql的新手,并且很难写出真正起作用的查询。

感谢。

编辑:哇。感谢您提供超级有用的答案和评论。我已经能够重写查询了。为了完整起见,我会把它放在这里,但功劳归属于约书亚·泰勒。

缩短查询次数

prefix skos: <http://www.w3.org/2004/02/skos/core#>
prefix envthes: <http://vocabs.lter-europe.net/EnvThes/>
select * {
  values ?category { envthes:10004 }
  ?concept skos:broader* ?category .
  ?concept skos:prefLabel ?prefLab .

  filter langMatches(lang(?prefLab), 'en')
  optional {
    ?concept skos:altLabel ?altlab
    filter langMatches(lang(?altLabel), 'en')
  }.
  OPTIONAL {?concept skos:altLabel ?altlab.
  FILTER (lang(?altlab)='en').}.
  OPTIONAL {?concept skos:broader ?parent.
    ?parent skos:prefLabel ?parLab .
  }.
}

1 个答案:

答案 0 :(得分:2)

这与您的查询不完全相同,我可能已经颠倒了概念和类别之间的链接方向(我永远不会记住 skos:更广泛的确切语义,以及它应该去哪个方向)。不过,这里的主要变化是使用前缀来提高查询的可读性,并使用属性路径( skos:wide * )来链接 ?类别?概念。我还使用块将?concept 绑定到您提到的特定固定值。

prefix skos: <http://www.w3.org/2004/02/skos/core#>

select * {
  #-- specify the value for ?category (you can just
  #-- use this inline, too, but defining it with
  #-- values makes it easier to add others later, and
  #-- can make the query easier to read)
  values ?category { <http://vocabs.lter-europe.net/EnvThes/10004> }

  #-- require that ?concept is related to ?category
  #-- by a chain skos:broader properties of length
  #-- zero or more.  (Zero means that ?concept can be
  #-- ?category.  Use skos:broader+ to require a path
  #-- of length one or more.)
  ?concept skos:broader* ?category .

  #-- get an preferred label in English (required)
  ?concept skos:prefLabel ?prefLab .
  filter langMatches(lang(?prefLab), 'en')

  #-- get an alternative label in English (optional)
  optional {
    ?concept <http://www.w3.org/2004/02/skos/core#altLabel> ?altlab
    filter langMatches(lang(?altLabel), 'en')
  }
}