2015-09-29 3 views
1

Возьмем следующий график:SPARQL: Выбор п-й blanknode

:Foo :p _:b0 ; 
    :p _:b1 ; 
    :p _:b2 . 

_:b0 :p1 :apple ; 
    :p2 :banana . 

_:b1 :p3 :cantaloupe ; 
    :p4 :date ; 
    :p5 :elderberry . 

_:b2 :p6 :fig . 

Примечание::Foo является предметом трех троек с тем же предикатом, :p. Каждый из этих троек имеет свой пустой объект.


Можно ли написать запрос SPARQL, который выбирает все тройки, где только _:b1 является предметом?


EDIT: Прежде чем предложить ответ, пожалуйста, поймите, что я ищу умного решения на мой вопрос, в SPARQL. Предположим, что тройное хранилище исправлено (т. Е. Ничего не может быть сделано для изменения данных). График, показанный выше, изобретателен; каждая пустая строка не имеет такого же количества троек p/o. Если каждый из них был один тройной однако, то следующий запрос SPARQL может быть достаточно:

select ?b1 where { 
    :Foo :p ?bn . 
    ?bn ?p ?o 
} limit 1 offset 1 

Очевидно, что беспокойство здесь возвращается тот же blanknode каждый раз. Я знаю, что это набор и по своей сути неупорядочен, поэтому не гарантируется повторяемость результатов; но, честно говоря ... для исправленного трехместного магазина, я искренне сомневаюсь, что DFA вернет различные порядковые номера между запросами. Какие-нибудь умные идеи?

ответ

4

Вы не можете выбрать «п-й» пустого узла в SPARQL, по двум причинам:

  1. модели RDF является набором: тройки неупорядоченные.
  2. пустой узел представляет ресурс без идентификатора - что означает, что он не может быть (напрямую) адресован/идентифицирован.

В RDF/SPARQL вы работаете с пустыми узлами непрямым способом: вместо того, чтобы пытаться обращаться к ним напрямую (что, как мы видели выше, невозможно, поскольку само определение пустого узла заключается в том, что он не имеет идентификатора), вы смотрите на то, что связывает их с другими ресурсами, то есть с заявлениями, в которых они участвуют. В конце концов, утверждения дают пустому узлу его контекстуальный смысл.

В вашем случае: различия между _:b1 и двумя другими пустыми узлами находятся в операторах, в которых они играют роль субъекта. Поэтому для запроса в SPARQL для троек, где находится _:b1, вы должны посмотреть данные и увидеть, что у _:b1 уникально есть свойство :p3 со значением :cantaloupe. Таким образом, вы можете запросить так:

CONSTRUCT { ?s ?p ?o } 
    WHERE { :Foo :p ?s . 
      ?s :p3 :cantaloupe ; 
       ?p ?o . 
    } 

На стороне записки: несколько реализаций двигателя SPARQL предлагают некоторые функциональные возможности для работы вокруг проблемы пустых узлов, не имеющих (глобальный) идентификатора. Во многих случаях они вводят некоторое нестандартное расширение синтаксиса или пользовательскую функцию, которая позволяет вам напрямую обращаться к пустому узлу в запросе SPARQL. Я хочу подчеркнуть, что это нестандартный, вряд ли работающий через разные конечные точки, и поэтому его лучше избегать.

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

UPDATE Какого обновление на вопрос в основном спрашивает это: «Могу ли я использовать некоторые недокументированные функции в неназванной конкретной реализации SPARQL сделать запрос, который, строго говоря, не является законным, или не гарантируются чтобы дать результат, который я хочу, и уйти с ним? Ответ на этот вопрос: возможно, да, но зависит от того, какую реализацию SPARQL вы используете, и это Очень плохой идеей по всем причинам, которые я вам дал выше.

Многие (наиболее?) Триплестры действительно дадут тот же результат в том же порядке между запросами на практике, хотя , что не гарантируется (я не могу это подчеркнуть), и вы действительно не должны полагаться на Это. Конечно, вы можете получить упорядоченный результат запроса, используя предложение ORDER BY по вашему запросу, но это не поможет в этом случае, так как относительный порядок пустых узлов не определен в SPARQL (поэтому механизм запроса может возвращать _:b1 и _:b2 в любом порядке, который он считает нужным, даже если есть пункт ORDER BY). Еще хуже: хотя ваш входной файл RDF может содержать идентификаторы пустых узлов _:b1 и _:b2, это не обязательно то, что возвращает запрос SPARQL. Многие триплестры заменяют идентификаторы пустых узлов с внутренне созданными идентификаторами, и ваш запрос SPARQL так же вероятно возвращает _:genid-908c909aeacc4b6da3d3059e18706d68-b1, а не просто _:b1.

И даже если вы могли бы вернуть пустой идентификатор узла надежно каким-то образом: что вы собираетесь с ним делать? Пустой узел пуст. Идентификатор, который он несет, предназначен только для внутренних учетных записей - вы не можете использовать пустой узел для запроса чего-либо еще.

Поверьте мне: это плохая идея. Если вы не можете изменить данные, полагайтесь на свойства, которые соединяют пустые узлы и запрашивают их.

+0

Я знаю, * вздох * ... но спасибо, что нашли время, чтобы написать это для других. Я обновил свой вопрос. –

+0

@BlakeRegalia обновил мой ответ. –

Смежные вопросы