"или" в запросе SPARQL
Я не совсем понимаю, почему в SPARQL не реализованы основные логические операторы. Однако в большинстве случаев можно получить один и тот же результат несколькими способами.
Цель этого вопроса - получить краткую справку о возможных путях, которые могут заменить оператор "или".
Вот что я могу придумать:
1)UNION
например:
SELECT * WHERE
{ { ?s :propA ?o } UNION { ?s :propB ?o } }
-не часто подходит, потому что это может стать очень многословным, потому что
SELECT * WHERE {
{ GRAPH ?g {?s ?p ?o. ?o ?pp ?data1}} UNION
{ GRAPH ?g {?s ?p ?o. ?o ?pp ?data2}}
}
не работает как
SELECT * WHERE {
GRAPH ?g {
?s ?p ?o.
{?o ?pp ?data1} UNION
{?o ?pp ?data2}
}
}
(по крайней мере, не со Stardog)
2)FILTER
например:
SELECT * WHERE
{
?s ?p ?o.
FILTER (?p = :propA || ?p = :propB )
}
Есть другие идеи?
2 ответа
Я не совсем уверен, почему вы говорите, что SPARQL не предоставляет "основные логические операторы", потому что ваши собственные примеры ясно показывают, что он делает: он предоставляет логическое ИЛИ (||
) и логически-И (&&
) как часть FILTER
условия и дизъюнктивные графовые шаблоны с использованием UNION
(конечно, шаблоны конъюнктивного графа не нуждаются в специальном синтаксисе).
Другие варианты OR
-подобные конструкции также возможны. Для запросов вида "это конкретное значение должно быть одной из этих возможностей" вы можете использовать оператор набора членства, IN
:
SELECT *
WHERE {
?s ?p ?o.
FILTER (?p IN (:propA, :propB, :propC ) )
}
Вы также можете использовать VALUES
пункт для этого вида шаблона:
SELECT *
WHERE {
VALUES ?p { :propA :propB :propC }
?s ?p ?o.
}
Обновление я забыл один, пожалуй, самый простой. Для таких запросов, как ваш, где вы ищете несколько альтернатив для имени свойства, вы также можете использовать выражение пути свойства, например, так:
SELECT *
WHERE {
?s :propA|:propB|:propC ?o.
}
Если вы хотите отследить, какой предикат приводит к какому объекту, тогда это универсальное решение для "ИЛИ":
SELECT DISTINCT ?s ?o1 ?o2
WHERE {
{
?s p1 ?o1 .
OPTIONAL
{
?s p2 ?o2 .
}
}
UNION
{
?s p2 ?o2 .
OPTIONAL
{
?s p1 ?o1 .
}
}
}