2009-11-19 2 views
9

В этом простом SPARQL запроса получить список предметов, цель которой 42Как привязать переменную к запрошенной элементу SPARQL

SELECT ?v WHERE { ?v ?p 42 } 

Если добавить? Р в качестве переменной

SELECT ?v ?p WHERE { ?v ?p 42 } 

Я получу два объекта в строке, тему и предикат. Что делать, если я хотел три объекта, так что в том числе 42? Что-то вроде:

SELECT ?v ?p ?m WHERE { ?v ?p (42 as m) } 
+1

Если 42 действительно константа, почему и вперед и назад? Когда вы получаете строки с двумя элементами, вы можете просто добавить третий. Или этот пример упрощен, и вы пытаетесь сделать что-то более сложное? –

+1

Просто любопытство. –

+0

@StefanoBorini SPARQL 1.0 сделал это немного неудобно, но SPARQL 1.1 включает в себя 'values' только для этой цели (и вы можете указать более одного постоянного значения для встроенных данных). Я добавил ответ. –

ответ

6

Стандарт SPARQL 1.0 на самом деле не позволяет этого. Однако могут быть некоторые расширения для реализации.

В качестве обходного пути, если данные содержат тройку с 42 в качестве объектного литерала, вы можете сделать это, например. как это:

SELECT ?v ?p ?m { ?v ?p 42, ?m FILTER(?m=42)} 

, который эквивалентен

SELECT ?v ?p ?m WHERE { ?v ?p 42 . ?v ?p ?m FILTER(?m=42)} 

, как вы можете написать график шаблоны обмена и тот же предмет и предикат объекта запятой список обозначений, а WHERE необязательное ключевое слово.

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

+0

Только что понял, что это не работает должным образом - это приводит к выбору любых троек, у которых есть тот же объект и предикат, что и те, у которых есть объект 42, поэтому вы можете получить нагрузку из разных троек, которые не имеют отношения к вашему запросу. – RobV

+0

@RobV: True , Спасибо что подметил это. Я пересмотрел ответ. – laalto

+0

Да, это прекрасно работает сейчас. – RobV

1
select ?v ?p ?m where { ?v ?p ?m . FILTER(?m = 42) } 
+1

Это казалось бы разумным, но в зависимости от вашего механизма Triple Store и SPARQL он, вероятно, будет очень неэффективным, так как многие двигатели SPARQL используют FILTERs в памяти, что означает, что вы эффективно загружаете весь набор данных (поскольку ? v? p? m соответствует всем), а затем FILTER над всем этим для объектов, которые являются 42 – RobV

+0

Правда, но любая функция SPARQL может быть неэффективной в зависимости от Triple Store. Например, LIMIT и OFFSET кажутся разумными, они должны работать быстро, не так ли? Например, на AllegroGraph это инструкции по постобработке, поэтому очень медленно, если у вас много данных. Что касается фильтра, FILTER, по крайней мере, на Virtuoso он очень эффективен, он переводит на очень простой SQL-запрос только с двумя условиями WHERE. –

+0

Для простого FILTER, подобного этому, это переведет простой SQL-запрос, предполагающий, что ваш магазин основан на SQL. LIMIT и OFFSET обычно пост-обрабатываются в любой реализации SPARQL, так как вам нужно применять FILTER и ORDER BY, прежде чем вы сможете их применить, - я бы не ожидал, что они будут быстрыми по сравнению с большими наборами данных. В любом случае подход laalto более эффективен и более переносим в разных реализациях SPARQL. – RobV

0

Я знаю, что это круглый, но я считаю, что это выполнимо с подзапросом.

Это полезный шаблон, чтобы помочь вам работать на запрос в узком, прежде чем позволить ей свободно на весь набор данных:

SELECT ?v ?p ?m WHERE { 
    { SELECT 42 as ?m WHERE { } } 
    ?v ?p ?m . 
} 
+2

На самом деле, есть предложение добавить к sparql 1.1, чтобы сделать это более непосредственно. Если это когда-либо будет реализовано, тогда вы сможете использовать «BIND (42 AS? M)» вместо подзапроса. http://www.w3.org/TR/sparql11-query/#bind –

+1

На самом деле форма ** значений ** еще лучше и поддерживает несколько значений: 'values? m {42}? v? p? m '. –

5

В SPARQL 1.1, вы можете использовать VALUES для этого. Вы бы написать

SELECT ?v ?p ?m WHERE { 
    values ?m { 42 } 
    ?v ?p ?m 
} 
8

Другой вариант заключается в использовании BIND, например .:

SELECT ?v ?p ?m 
WHERE { 
    BIND(42 AS ?m) 
    ?v ?p ?m 
} 

Оператор BIND просто добавляет привязки для? М, которые затем могут быть выбраны для результирующего набора.

+0

thumb up - работает в python rdflib Реализация SPARQL – lowtech

1

Вы можете осуществить двумя способами, используя ПРИВЯЗКИ ключевое слово, а также ФИЛЬТР

Использование ПРИВЯЗКИ

SELECT ?v ?p ?m 
WHERE { ?v ?p ?m} 
BINDINGS ?m {(42)} 

Использование ФИЛЬТР

SELECT ?v ?p ?m 
WHERE { 
?v ?p ?m 
FILTER (?m = 42) 
} 
+0

['VALUES' заменил и обобщил' BINDINGS'] (https://www.w3.org/TR/2012/WD-sparql11-query-20120724/#status) в последнем вызове Рабочий проект языка запросов SPARQL 1.1 –

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