"или" в запросе 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 .
     }
  }
}
Другие вопросы по тегам