Как вернуть конкретную переменную из SPARQL Federated Query (ключевое слово Service)? - PullRequest
0 голосов
/ 13 ноября 2018

Я использую федеративный запрос для получения некоторой информации с удаленного сервера, но я не хочу извлекать все переменные (выберите *), над которыми я работаю внутри федеративного запроса, я хочу просто вернутьпеременная count.Как я могу это сделать?

Код:

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> .

}

Но в федеративном запросе я не могу выбрать переменные, поэтому есть ли способ сделать то, что я хочу?

** EDIT 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 федеративный запрос выбирает все (*), кромепроблема в том, что я не хочу получать все эти отношения, которые я имею в виду в федеративном запросе, я просто хочу получить счетчик, но сount - это расширенная функция, которую можно размещать только перед ключевым словом 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 биологического процесса, как показано на рисункениже:

imageExplain the subquery inside the federated query">

Учитывая это, как я могу получить только счет из федеративного запроса?

Извините за длинный пост.

1 Ответ

0 голосов
/ 13 ноября 2018

Как и в Использование службы меток Wikidata в федеративных запросах , включить некоторые вещи, которые являются номинально необязательными ...

Примечание. Ваш удаленный запрос должен выполняться на удаленной конечной точке, иначе вы получите различные ошибки.

Это запрос, который вы пытаетесь выполнить на конечной точке Uniprot -

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

- но это не из-за синтаксической ошибки; это связано с ZeroOrMorePath свойств rdfs:subClassOf или owl:someValuesFrom ((rdfs:subClassOf|owl:someValuesFrom)*) Запрашиваемый путь свойства, который должен использовать МНОГИЕ возможности.

Если вы ограничите глубину этого пути, конечная точка Uniprot сможет с этим справиться, и вы сможете запустить ее через 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 (который разрешает федеративный 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 действуют разные настройки, когда вы напрямую переходите через форму веб-запроса, которая использует JDBC к их серверу SPARQL, а затем, когда вы идете прямо через HTTP, как с Federated SPARQL.

Я думаю, что решение , которое вам нужно, - это локальное зеркало Uniprot или подключение к общедоступному экземпляру Uniprot, который имеет другие разрешения / настройки, чем основная общедоступная конечная точка.

...