web-dev-qa-db-fra.com

"ou" dans une requête SPARQL

Je ne comprends pas très bien pourquoi dans SPARQL ils n'ont pas implémenté les opérateurs de logique de base. Cependant, dans la plupart des cas, il est possible d'obtenir le même résultat de plusieurs manières.

Le but de cette question est d'avoir une référence rapide pour les voies possibles qui peuvent remplacer une déclaration "ou".

Voici ce à quoi je peux penser:

1) UNION

par exemple:

SELECT * WHERE
{  { ?s :propA ?o } UNION { ?s :propB ?o }  }

-pas souvent adapté car il peut devenir très verbeux car

SELECT * WHERE { 
    { GRAPH ?g {?s ?p ?o. ?o ?pp ?data1}} UNION 
    { GRAPH ?g {?s ?p ?o. ?o ?pp ?data2}}
} 

ne fonctionne pas comme

SELECT * WHERE { 
    GRAPH ?g {
       ?s ?p ?o. 
       {?o ?pp ?data1} UNION 
       {?o ?pp ?data2} 
    }
 }

(du moins pas avec Stardog)

2) FILTER

par exemple:

SELECT * WHERE
    { 
        ?s ?p ?o.
        FILTER (?p = :propA || ?p = :propB )
    }

D'autres idées?

19
ffa

Je ne sais pas vraiment pourquoi vous dites que SPARQL ne fournit pas "les opérateurs logiques de base", car vos propres exemples montrent clairement que c'est le cas: il fournit un OU logique (||) et logique-ET (&&) dans le cadre des conditions FILTER et des motifs de graphe disjonctifs utilisant UNION (bien sûr, les motifs de graphe conjonctif n'ont pas besoin de syntaxe spéciale).

D'autres variantes de constructions semblables à OR sont également possibles. Pour les requêtes de la forme "cette valeur particulière doit être l'une de ces possibilités", vous pouvez utiliser l'opérateur d'appartenance set, IN:

SELECT * 
WHERE { 
    ?s ?p ?o.
    FILTER (?p IN (:propA, :propB, :propC ) )
}

Vous pouvez également utiliser la clause VALUES pour ce type de modèle:

SELECT * 
WHERE {
    VALUES ?p { :propA :propB :propC } 
    ?s ?p ?o.
}

pdate J'en ai oublié un, peut-être le plus simple. Pour les requêtes telles que la vôtre, où vous recherchez quelques alternatives pour un nom de propriété , vous pouvez également utiliser une expression de chemin de propriété, comme ceci :

SELECT * 
WHERE {
    ?s :propA|:propB|:propC ?o.
}
26
Jeen Broekstra

Si vous voulez tracer quel prédicat mène à quel objet, alors c'est la solution universelle pour "OU":

SELECT DISTINCT ?s ?o1 ?o2 
WHERE {
  {
     ?s p1 ?o1 .
     OPTIONAL
     {
        ?s p2 ?o2 .
     }
  } 
  UNION 
  {
     ?s p2 ?o2 .
     OPTIONAL
     {
        ?s p1 ?o1 .
     }
  }
}
3
Marko Djurovic