Пример, который вы опубликовали, демонстрирует один из угловых случаев спецификации SPARQL, который объединяет несколько связанных тем и, на мой взгляд, весьма неоднозначно.Детали ниже объясняют, каковы принятые предположения и проектные решения в движке GraphDB.Обратите внимание, что это может отличаться от способа, которым другие реализации читают следующие строки спецификации:
Взаимодействие SERVICE и ЗНАЧЕНИЙ
Федерация SPARQL 1.1 имеет ненормативный раздел, описывающий поведение в этом случае:
Разработчики SPARQL 1.1 Federated Query могут использовать предложение VALUES для ограничения результатов, полученных от удаленной конечной точки, на основе привязок решенияот оценки других частей запроса.
Оптимизатор запросов GraphDB не может получить какую-либо статистику с удаленной конечной точки SPARQL, поэтому он использует подход, чтобы наивно накидывать запрос на удаленный SERVICE и локально объединять результаты.Таким образом, задача оптимизации запросов находится в руках пользователя, который знает схему в двух репозиториях, переставив запрос процедурным способом (см. Ниже).
Федеративные запросы являются подзапросами
Каждый удаленный запрос обрабатывается как подзапрос и отправляется как есть на внешнюю конечную точку.Вот эквивалентный синтаксис:
# remote service
SERVICE <https://query.wikidata.org/sparql> {
SELECT ?cat ?membership {
?cat wdt:P463 ?membership
}
LIMIT <put any limit>
}
Сначала выполняются подзапросы, а все переменные распространяются снизу вверх
В соответствии со спецификацией SPARQL , в подзапросе нельзя вставлять привязки переменных:
Подзапросы - это способ встраивания запросов SPARQL в другие запросы, обычно для достижения результатов, которые иначе не могут быть достигнуты, напримеркак ограничение количества результатов из некоторого подвыражения в запросе.
Из-за восходящей природы оценки запроса SPARQL сначала выполняются логические подзапросы, а результаты проецируются до внешнего запроса..
Обратите внимание, что только переменные, спроецированные из подзапроса, будут видны или находятся в области видимости для внешнего запроса.
На этом этапе больше невозможно эффективно выполнять запросыс очень избирательным местным предложением.Вот почему база данных GraphDB предоставляет специальный параметр конфигурации, который нарушает соответствие спецификации SPARQL:
./graphdb -Dreuse.vars.in.subselects
В этом случае механизм запросов будет игнорировать спецификацию SPARQL и будет выдаватьпеременная из внешнего запроса внутри суб-выбора.Правильная версия запроса после включения этого параметра:
PREFIX : <http://my_awesome_cats_collection#>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
select * where {
?cat :name ?name .
VALUES ?name {
'Marble'
}
# remote service
SERVICE <https://query.wikidata.org/sparql> {
?cat wdt:P463 ?membership
}
}
Как использование должно оптимизировать план выполнения запросов удаленных конечных точек
VALUES /BIND являются процедурными, и их место является значительным в соответствии со спецификацией SPARQL
Форма BIND позволяет присваивать значение переменной из базового графового шаблона или выражения пути свойства.Использование BIND завершает предыдущий базовый графовый шаблон.Переменная, введенная предложением BIND, не должна использоваться в шаблоне группового графа вплоть до точки использования в BIND.
Другая форма того же запроса, гораздо менее эффективная в данном конкретном случае, заключается всначала выполните запрос удаленной конечной точки (то есть загрузите все результаты из Викиданных), а затем объедините их с локальным меньшим набором дат:
PREFIX : <http://my_awesome_cats_collection#>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
select * where {
# remote service
SERVICE <https://query.wikidata.org/sparql> {
?cat wdt:P463 ?membership
}
?cat :name ?name .
VALUES ?name {
'Marble'
}
}
Я надеюсь, что это даст вам полное представление о интерпретации GraphDB спецификации SPARQL ивсе возможности оптимизации федеративных запросов.