SPARQL 获取所有节点的所有父节点

SPARQL to get all parents of all nodes

我一直在使用这个 post 来获取单个 RDF 节点的父节点或沿袭节点:SPARQL query to get all parent of a node

这在我的 virtuoso 服务器上运行良好。抱歉,找不到包含具有类似结构的数据的 public 端点。

prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix bto: <http://purl.obolibrary.org/obo/>
select (group_concat(distinct ?midlab ; separator = "|") AS ?lineage)
where
{ 
  bto:BTO_0000207 rdfs:subClassOf* ?mid .
  ?mid rdfs:subClassOf* ?class .
  ?mid rdfs:label ?midlab .
}
group by ?lineage
order by (count(?mid) as ?ordercount)

给予

+---------------------------------------------------------+
|                         lineage                         |
+---------------------------------------------------------+
| bone|cartilage|connective tissue|tibia|tibial cartilage |
+---------------------------------------------------------+

然后我想知道是否可以通过将 select 更改为

来获取所有节点的沿袭
select ?s (group_concat(distinct ?midlab ; separator = "|") AS ?lineage)

和 where 语句中的第一行

?s rdfs:subClassOf* ?mid .

SPARQL 经验比我丰富的人可能不会对查询超时感到惊讶。

这种做法合理吗?我在语法上做错了什么吗?

我怀疑 distinct 关键字或组子句是瓶颈,因为这只需要一两秒钟:

prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix bto: <http://purl.obolibrary.org/obo/>
select ?s ?midlab
where
{ 
  ?s rdfs:subClassOf* ?mid .
  ?mid rdfs:subClassOf* ?class .
  ?mid rdfs:label ?midlab .
  ?s <http://www.geneontology.org/formats/oboInOwl#hasOBONamespace> "BrendaTissueOBO"^^<http://www.w3.org/2001/XMLSchema#string> .
}

您的第一个查询不合法。您可以在 sparql.org's query validator 查看。虽然您可以 按 count(?mid) 排序,但不能将值绑定到变量并在同一子句中按它排序。那会给你:

select (group_concat(distinct ?midlab ; separator = "|") AS ?lineage)
where
{ 
  bto:BTO_0000207 rdfs:subClassOf* ?mid .
  ?mid rdfs:subClassOf* ?class .
  ?mid rdfs:label ?midlab .
}
group by ?lineage
order by count(?mid)

现在,那是 合法的 ,但它并没有多大意义。 group_concat 要求您有一些组,并且您将对每个组中的值进行串联。在没有 group by 子句的情况下,您会得到一个隐式组,因此没有 group 的 group_concat by 可以。但是你有一个 group by ?lineage 这没有多大意义,因为 ?lineage 已经只有一个值组(因为它已经是一个聚合)。更好的方法是 group by ?s,如下所示。这似乎更正确,并且可能不会超时:

select ?s (group_concat(distinct ?midlab ; separator = "|") AS ?lineage)
where
{ 
  ?s rdfs:subClassOf* ?mid .
  ?mid rdfs:subClassOf* ?class .
  ?mid rdfs:label ?midlab .
}
group by ?s
order by count(?mid)