首页 文章

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

提问于
浏览
2

我正在使用联合查询从远程服务器检索一些信息,但我不想检索我在联合查询中正在处理的所有变量(select *),我想只返回count变量 . 我怎样才能做到这一点?

Code:

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中所有已识别的蛋白质 .

The full SPARQL code:

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替换,如下图所示:

Explain the subquery inside the federated query

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

抱歉这篇长篇文章 .

1 回答

  • 2

    Using Wikidata label service in federated queries,包括一些名义上可选的东西......

    注意 - 您的远程查询必须实际在远程 endpoints 上执行,否则您将获得不同的错误 .

    这是您尝试在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执行失败:[PREFIX up:PREFIX taxon:PREFIX rdfs:PREFIX owl:SELECT(COUNT(DISTINCT?protein)AS?count)WHERE {?sub_bp(rdfs:subClassOf | owl:someValuesFrom)*?bp_iri . ?蛋白质上升:分类与?sub_bp . ?蛋白质上升:有机体分类:10090 . 例外:virtuoso.jdbc4.VirtuosoException:TN ...:在传递临时内存中超过1000000000字节 . 使用t_distinct,t_max或更多T_MAX_memory选项来限制搜索或增加池

    • 但是's not due to a syntax error; it'由于您正在查询的 rdfs:subClassOfowl:someValuesFrom 属性( (rdfs:subClassOf|owl:someValuesFrom)* )属性路径的ZeroOrMorePath,它必须尝试多种可能性 .

    如果限制该路径的深度,Uniprot endpoints 可以处理它,您可以通过Federated 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运行此查询(它允许经过身份验证的用户使用Federated 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客户端中的读取错误

    • 这表明当你直接浏览他们的Web查询表单时,Uniprot服务器上会有不同的设置,它使用JDBC来对抗他们的SPARQL服务器,然后直接通过HTTP,就像使用Federated SPARQL一样 .

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

相关问题