如何从SPARQL联合查询(服务关键字)返回特定变量?

时间:2018-11-12 22:37:36

标签: sparql jena arq federated-queries

我正在使用联合查询从远程服务器检索一些信息,但是我不想检索联合查询中正在处理的所有变量(选择*),我只想返回计数变量。我该怎么办?

代码:

SERVICE <https://sparql.uniprot.org/sparql/> {
    ?sub_bp (rdfs:subClassOf|owl:someValuesFrom)* ?bp_iri .
    ?protein up:classifiedWith ?sub_bp.
    ?protein up:organism <http://purl.uniprot.org/taxonomy/10090> .
}

如果不是联邦查询,我会这样做:

SELECT distinct (count(distinct ?protein) as ?count) WHERE {

  ?sub_bp (rdfs:subClassOf|owl:someValuesFrom)* ?bp_iri .
  ?protein up:classifiedWith ?sub_bp.
  ?protein up:organism <http://purl.uniprot.org/taxonomy/10090> .

}

但是在联合查询中,我无法选择变量,那么有什么方法可以做我想要的吗?

**编辑1 **

在@TallTed回复后,我注意到为了简化问题,我可能已经跳过了一些细节,但是事实证明这些细节很重要,因此我将描述整个情况。

我有一个本地数据集,其中包含有关生物学过程和基因的三元组。我必须计算与每个生物过程相关的基因数,然后将该数字除以Uniprot中鉴定出的关于同一生物过程(及其“子代”)的蛋白质总数。

为此,我首先查询我的本地数据集,计算每个生物过程的基因,然后运行联合查询以计算每个生物过程(及其“子代”)的Uniprot中所有已鉴定的蛋白质。

完整的SPARQL代码:

PREFIX obo: <http://purl.obolibrary.org/obo/>
PREFIX rdfs:    <http://www.w3.org/2000/01/rdf-schema#>
PREFIX uniprot:    <http://purl.uniprot.org/core/>
PREFIX up:<http://purl.uniprot.org/core/>
PREFIX owl:<http://www.w3.org/2002/07/owl#> 

SELECT DISTINCT ?bp_iri ?bp_count (count(distinct ?protein) as ?bp_total) ((?bp_count / ?bp_total) as ?divided) WHERE {

    { 
        SELECT DISTINCT ?bp_iri (COUNT(?bp_iri) as ?bp_count) WHERE{
            ?genes_iri a uniprot:Gene .
            ?genes_iri obo:RO_0000056 ?bp_iri .
        }group by ?bp_iri order by DESC(?bp_count)

    }

    SERVICE silent <https://sparql.uniprot.org/sparql/> {
        ?sub_bp (rdfs:subClassOf|owl:someValuesFrom)* ?bp_iri .
        ?protein up:classifiedWith ?sub_bp.
        ?protein up:organism <http://purl.uniprot.org/taxonomy/10090> .
    }

}group by ?bp_iri ?bp_count ?bp_total order by DESC(?divided)

当我使用Jena ARQ(查询引擎)运行此查询时,变量?bp_iri在HTTP请求时被特定的生物过程IRI(每个生物过程一个HTTP请求)替换,如下所示。下图:

SPARQL explain of the federated query

请注意,在explain图像中,联合查询正在选择所有内容(*),但是问题是我不想检索我在联合查询中处理的所有这些关系,我只是想要检索计数,但是该计数是一个综合函数,只能将其放在关键字SELECT的前面。 (我不想检索所有关系,因为这些查询返回很多三元组(成千上万,有时甚至数百万个),并且不必为了计数而将它们放入我的计算机。)

为解决此问题,我尝试在联合查询中创建一个子查询,以仅选择计数(?bp_total),而不选择所有三元组。使用的代码:

SERVICE silent <https://sparql.uniprot.org/sparql/> {
    {
        SELECT (count(distinct ?protein) as ?bp_total) WHERE {
            ?sub_bp (rdfs:subClassOf|owl:someValuesFrom)* ?bp_iri .
            ?protein up:classifiedWith ?sub_bp.
            ?protein up:organism <http://purl.uniprot.org/taxonomy/10090> .
        }
    }
}

再次运行explain时,我注意到当在联合查询中放入子查询时,变量?bp_iri不会被生物过程IRI代替,如下图所示:

<code>Explain</code> the subquery inside the federated query

考虑到这一点,如何仅从联合查询中检索计数?

很抱歉,帖子很长。

1 个答案:

答案 0 :(得分:2)

Using Wikidata label service in federated queries中一样,包括名义上可选的一些内容...

请注意-您的远程查询必须实际上在远程端点上执行,否则您将获得各种错误。

这是您要在Uniprot endpoint上运行的查询-

PREFIX    up: <http://purl.uniprot.org/core/> 
PREFIX taxon: <http://purl.uniprot.org/taxonomy/> 
PREFIX  rdfs: <http://www.w3.org/2000/01/rdf-schema#> 
PREFIX   owl: <http://www.w3.org/2002/07/owl#> 

SELECT (COUNT(DISTINCT ?protein) AS ?count) 
WHERE
  {
    ?sub_bp  (rdfs:subClassOf|owl:someValuesFrom)*  ?bp_iri .
    ?protein  up:classifiedWith  ?sub_bp .
    ?protein  up:organism        taxon:10090 .
  }

出现错误-

  

查询评估异常。

     

: SPARQL execute failed:[PREFIX up: PREFIX taxon: PREFIX rdfs: PREFIX owl: SELECT (COUNT(DISTINCT ?protein) AS ?count) WHERE { ?sub_bp (rdfs:subClassOf|owl:someValuesFrom)* ?bp_iri . ?protein up:classifiedWith ?sub_bp . ?protein up:organism taxon:10090 . }] Exception:virtuoso.jdbc4.VirtuosoException: TN...: Exceeded 1000000000 bytes in transitive temp memory. use t_distinct, t_max or more T_MAX_memory options to limit the search or increase the pool

-但这不是由于语法错误;这是由于您要查询的rdfs:subClassOfowl:someValuesFrom属性((rdfs:subClassOf|owl:someValuesFrom)*)属性路径的ZeroOrMorePath,必须尝试许多可能性。

如果您限制该路径的深度,则Uniprot端点可以处理它,并且可以通过联合SPARQL运行它。

这是一个深度减少的查询(我使用3个“ ZeroOrOnePath”任意尝试了)-

PREFIX    up: <http://purl.uniprot.org/core/> 
PREFIX taxon: <http://purl.uniprot.org/taxonomy/> 
PREFIX  rdfs: <http://www.w3.org/2000/01/rdf-schema#> 
PREFIX   owl: <http://www.w3.org/2002/07/owl#> 

SELECT (COUNT(DISTINCT ?protein) AS ?count) 
WHERE
  {
    ?sub_bp  (rdfs:subClassOf|owl:someValuesFrom)? 
             / (rdfs:subClassOf|owl:someValuesFrom)? 
             / (rdfs:subClassOf|owl:someValuesFrom)?   ?bp_iri .
    ?protein  up:classifiedWith  ?sub_bp .
    ?protein  up:organism        <http://purl.uniprot.org/taxonomy/10090> .
  }

-得到了结果-

count
"77633"xsd:int

-我发现在单个级别上都是相同的结果-

PREFIX    up: <http://purl.uniprot.org/core/> 
PREFIX taxon: <http://purl.uniprot.org/taxonomy/> 
PREFIX  rdfs: <http://www.w3.org/2000/01/rdf-schema#> 
PREFIX   owl: <http://www.w3.org/2002/07/owl#> 

SELECT (COUNT(DISTINCT ?protein) AS ?count) 
WHERE
  {
    ?sub_bp  (rdfs:subClassOf|owl:someValuesFrom)?  ?bp_iri .
    ?protein  up:classifiedWith  ?sub_bp .
    ?protein  up:organism        <http://purl.uniprot.org/taxonomy/10090> .
  }

我刚刚通过URIBurner.com(允许经过身份验证的用户使用联合SPARQL)运行此查询-

PREFIX    up: <http://purl.uniprot.org/core/> 
PREFIX taxon: <http://purl.uniprot.org/taxonomy/> 
PREFIX  rdfs: <http://www.w3.org/2000/01/rdf-schema#> 
PREFIX   owl: <http://www.w3.org/2002/07/owl#> 

SELECT *
WHERE
  {
    SERVICE <https://sparql.uniprot.org/sparql>
      {
        SELECT (COUNT(DISTINCT ?protein) AS ?count) 
        WHERE
          {
            ?sub_bp  (rdfs:subClassOf|owl:someValuesFrom)?  ?bp_iri .
            ?protein  up:classifiedWith  ?sub_bp .
            ?protein  up:organism        <http://purl.uniprot.org/taxonomy/10090> .
          }
      }
  }

那仍然会产生错误-

  

Virtuoso HTCLI错误HC001:HTTP客户端中的读取错误

-表示当您直接通过Uniprot服务器的Web查询表单时,Uniprot服务器上会进行不同的设置,该表单对他们的SPARQL服务器使用JDBC,然后当您直接通过HTTP(如联合SPARQL)通过HTTP时。

我认为您需要的解决方案是本地Uniprot镜像,或与具有与主要公共终结点不同的权限/设置的公共Uniprot实例的连接。