Как улучшить медленный запрос с помощью FILTER (?id IN (…))

Я только начал использовать SPARQL и пытаюсь создать запрос, который извлекает всю информацию, где идентификатор имеет одно из нескольких предопределенных значений? У меня есть что-то вроде этого:

SELECT *
WHERE {
    ?id ?property ?value .
    ?value a ?type .
    ?type rdfs:label ?type_value .
    FILTER ( ?id IN (<id1>,<idi>,<idn> ) )
}

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

SELECT * 
WHERE {
    <id_value> ?property ?value .
    ?value a ?type .
    ?type rdfs:label ?type_value .
}

где он извлекает все значения только для нескольких идентификаторов, исключая фильтрацию результатов в конце, но я не могу понять, как написать запрос, чтобы он возвращал все значения для id_value. когда я добавляю еще одну строку для другого значения id_value, она отфильтровывает другие значения, которые я ожидаю, поэтому я думаю, что пишу это неправильно. Как я могу это сделать?


person rcheuk    schedule 15.11.2013    source источник
comment
Похоже, со временем я смогу перейти на virtuoso v.7, поэтому я попробую этот метод, как только получу обновление. Спасибо всем. Я опубликую свои выводы, как только я это сделаю!   -  person rcheuk    schedule 15.11.2013
comment
Спасибо всем! Предложение Values ​​имело огромное значение — 14-секундный запрос сократился до 2-4 секунд. (все еще ищу способы оптимизации, теперь смотрю на виртуозные настройки, чтобы увидеть, могу ли я что-то изменить, чтобы ускорить это, но это очень многообещающе!)   -  person rcheuk    schedule 21.11.2013


Ответы (2)


Используя values, вы можете написать:

SELECT * WHERE {
  values ?id { <id1> <idi> <idn> }
  ?id ?property ?value .
  ?value a ?type .
  ?type rdfs:label ?type_value .
}

SPARQL 1.1 говорит о values:

Данные могут быть непосредственно записаны в шаблон графика или добавлены в запрос с помощью ЗНАЧЕНИЙ. VALUES предоставляет встроенные данные в виде последовательности решений, которые объединяются с результатами оценки запроса с помощью операции соединения. Он может использоваться приложением для предоставления определенных требований к результатам запроса, а также реализациями механизма запросов SPARQL, которые обеспечивают объединенный запрос с помощью ключевого слова SERVICE для отправки более ограниченного запроса в удаленную службу запросов.

Один из примеров на самом деле очень близок к тому, что у вас уже есть:

PREFIX dc:   <http://purl.org/dc/elements/1.1/> 
PREFIX :     <http://example.org/book/> 
PREFIX ns:   <http://example.org/ns#> 

SELECT ?book ?title ?price
{
   VALUES ?book { :book1 :book3 }
   ?book dc:title ?title ;
         ns:price ?price .
}
person Joshua Taylor    schedule 15.11.2013
comment
Спасибо... к сожалению, текущая конечная точка sparql, которую я использую (virtuoso 6.1.6), не поддерживает этот пункт. Я думаю, я посмотрю, что я могу сделать с обновлением ... - person rcheuk; 15.11.2013
comment
@harmlessdragon Хм, это все усложняет. Хотя это сделало бы ваш запрос длиннее, можете ли вы попробовать { <id1> ... } union ... union { <idn> ... } для сравнения и посмотреть, как он работает? Хотя текст будет длиннее, производительность должна быть намного лучше, поскольку вы будете получать только те результаты, которые хотите. - person Joshua Taylor; 15.11.2013
comment
Это уже пробовали, ха-ха... и получилось немного дольше, чем при использовании предложения FILTER. - person rcheuk; 15.11.2013
comment
@harmlessdragon Ой, это больно. :( - person Joshua Taylor; 15.11.2013

Попробуйте вместо этого использовать предложение VALUES следующим образом:

SELECT * 
WHERE {
    VALUES ?id { ...list of ids... }
    ?id ?property ?value .
    ?value a ?type .
    ?type rdfs:label ?type_value .
}

Мы надеемся, что это должно быть намного эффективнее, чем использование подхода FILTER.

person RobV    schedule 15.11.2013
comment
В некоторых комментариях к этому ответу мы (вы и я) немного обсуждали FILTER( ?document = ... || ?document = ... ) оптимизацию в union на основе запрос (но я думаю, что один из комментариев с тех пор был удален). Есть ли причина, по которой ?id in ( ... ) не следует оптимизировать таким же образом? - person Joshua Taylor; 15.11.2013
comment
Я столкнулся с пунктом values ​​ранее. К сожалению, текущая конечная точка sparql, которую я использую (virtuoso 6.1.6), не поддерживает этот пункт. Я думаю, я посмотрю, что я могу сделать с обновлением ... - person rcheuk; 15.11.2013
comment
@JoshuaTaylor В ARQ это так, ?id IN ( ) преобразуется в эквивалент ?id == <x> || ?id == <y> и т. д., а затем преобразуется в UNION. Однако оптимизаторы будут сильно различаться по своему поведению, особенно в случае чего-то вроде Virtuoso, где он компилирует SPARQL в SQL. - person RobV; 16.11.2013