2017-08-09 1 views
1

Ceci est une suite à ma question Compare models for identity, but with variables? Construct with minus?. Soit j'ai oublié ce que j'ai appris alors, soit je n'ai pas appris autant que je le pensais.sparql "diff" (moins avec quelques variables non partagées)

J'ai triplets comme ceci:

prefix : <http://example.com/> 

:rose :color :red . 
:violet :color :blue . 
:rose a :flower . 
:flower rdfs:subClassOf :plant . 
:dogs :love :trucks . 

Je veux découvrir les triplets dans mon triplestore qui ne satisfont pas au moins l'un des ces règles:

  1. prendre :rose comme sujet
  2. prendre la classe parente :rose comme sujet
  3. utilisation quelconque des prédicats qui sont utilisés dans tout triple avec :rose que le sujet
  4. prise, pour objet , l'objet quelle triple avec :rose que le sujet.

Ainsi, dans ce cas, la requête exception découverte (sélectionner ou construire) ne devrait retourner

:dogs :love :trucks . 

Cette requête montre ce devrait être dans le triplestore:

PREFIX : <http://example.com/> 
construct where { 
    :rose ?p ?o . 
    :rose a ?c . 
    ?c rdfs:subClassOf ?super . 
    ?s ?p ?x1 . 
    ?x2 ?x3 ?o 
} 

.

+---+---------+-----------------+---------+ 
| | subject | predicate | object | 
+---+---------+-----------------+---------+ 
| A | :flower | rdfs:subClassOf | :plant | 
| B | :rose | :color   | :red | 
| C | :rose | rdf:type  | :flower | 
| D | :violet | :color   | :blue | 
+---+---------+-----------------+---------+ 

est-il un moyen de soustraire ce modèle de tout dans le triplestore, { ?s ?p ?o }, même si je suis en utilisant des noms de variables autres que ?s, ?p et ?o dans la déclaration construct?

J'ai vu this post avec des stratégies pour comparer RDF, mais je voudrais le faire avec SPARQL standard.

Pour l'associer à mon article précédent, cette requête finale suggère à tort que plusieurs triplets souhaités violent les règles énoncées en haut du message.

+---------+-----------------+---------+ 
E | :dogs | :love   | :trucks | 
A | :flower | rdfs:subClassOf | :plant | 
D | :violet | :color   | :blue | 
    +---------+-----------------+---------+ 

Triple E est en effet indésirable. Mais A est souhaité, car il a pour sujet (règle 2) classe de :rose et triple D est souhaitée, car il est prédicat est également utilisé dans certains triplets avec: rose comme sujet (règle 3).

PREFIX :  <http://example.com/> 
CONSTRUCT 
    { 
    ?s ?p ?o . 
    } 
WHERE 
    { SELECT ?s ?p ?o 
    WHERE 
     { { ?s ?p ?o } 
     MINUS 
      { :rose ?p    ?o ; 
        rdf:type   ?c . 
      ?c  rdfs:subClassOf ?super . 
      ?s  ?p    ?x1 . 
      ?x2 ?x3    ?o 
      } 
     } 
    } 
+0

Pouvez-vous clarifier un peu? "si mon triplestore contient des triplets qui violent ces règles: 1. ne sont pas sur: rose 2 ..." La règle qui triple * devrait * être sur rose (et par là, voulez-vous dire "rose est le sujet" ou "rose est le sujet ou l'objet (ou prédicat)"), ou qu'ils ne devraient pas? Il n'est généralement pas trop difficile d'écrire des requêtes SPARQL qui détectent des violations de certaines règles, mais il est nécessaire de savoir quelles sont les règles **. –

+0

Merci. Je travaillais sur cette section vague quand vous avez posté! Est-ce mieux maintenant? J'ai plus d'exemples de ** comportement indésirable ** au fond non, aussi. –

+0

Le problème est que le 'MINUS' forme (comme d'habitude) un ensemble de séquences de solution et non un ensemble de triplets. Et en effet cela ne fonctionnera pas pour le soustraire d'autant plus que vous n'avez pas de variables partagées, mais ici il est plus important de ne pas soustraire des triplets dans une requête SELECT. – AKSW

Répondre

4

Si je comprends bien, vous voulez permettent quatre types de triplets dans vos données. Si un triple (s, p, o) est dans vos données, il doit satisfaire au moins un des critères suivants:

  1. s = rose (A propos de rose)
  2. p = rdfs: subClassOf, et données contient (rose, a, s) (a propos d'un type)
  3. Les données contiennent également (rose, p, x) (prédicat partagée)
  4. Les données contiennent également (rose, q, o (objet partagé)

Il est assez facile d'écrire un motif pour chacun d'entre eux. Vous avez juste besoin de trouver chaque triple (s, p, o) et filtrer ceux qui ne correspondent à aucun de ces critères. Je pense que vous pouvez le faire comme ceci:

select ?s ?p ?o { 
    ?s ?p ?o 
    filter not exists { 
      { values ?s { :rose } }      #-- (1) 
    union { values ?p { rdfs:subClassOf } :rose a ?s } #-- (2) 
    union { :rose ?p ?x }        #-- (3) 
    union { :rose ?x ?o }        #-- (4) 
    } 
} 
+0

C'est en effet une réponse correcte: D Fonctionne pour moi (testé avec Stardog 5.x): '(s, p, o): (: fleur, rdfs: subClassOf,: plante) | (: chiens,: amour,: camions) 'En effet, générer ce type de requête automatiquement pourrait être plus difficile, mais je suppose que ce n'était pas la question ici. À votre santé! – AKSW

+0

** Fonctionne comme demandé dans Blazegraph 2.1.1. ** * Renvoie 0 triplets dans GraphDB Free 8.2.0. * –

+0

Peut-être que GraphDB a des problèmes avec le 'VALUES' dans un' FILTER NOT EXISTS', qui est rarement utilisé dans combinaison - mais qui sait. – AKSW