4

For some reason I can't issue DESCRIBE queries using Redland ( librdf.org ), is it possible to rewrite DESCRIBE as a CONSTRUCT QUERY for a given URI?

DESCRIBE <urn:my-uri>

I was thinking about writting it into something like this but I don't think this is valid in SPARQL

CONSTRUCT  { ?subject ?predicate ?object }
WHERE      { 
               { ?subject ?predicate ?object } 
               AND { 
                   { <urn:my-uri> ?predicate ?object } 
                   OR { ?subject <urn:my-uri> ?object } 
                   OR { ?subject ?predicate <urn:my-uri> } 
               } 
           }
Jeffrey04
  • 6,138
  • 12
  • 45
  • 68

2 Answers2

3

After trying something like the FILTER ( A || B ) method, I got the impression that it is pretty slow.

I think you can do the same thing, basically, but using VALUES and UNION

I tried it on DBPedia (~2.46 billion triples) with a movie, and it seemed to perform well.

CONSTRUCT {
    ?subject ?predicate ?object
}
WHERE {
   { ?subject ?predicate ?object . 
       VALUES ?subject { dbpedia:The_Matrix }
   }
   UNION 
   { ?subject ?predicate ?object . 
       VALUES ?object { dbpedia:The_Matrix }
   }
}

sparql result on dbpedia


Edit: Just for the sake of additional info, I think you could technically also write the following:

CONSTRUCT { ?subject ?predicate ?object }
WHERE {
       ?subject ?predicate ?object . 
       OPTIONAL { dbpedia:The_Matrix ?predicate ?object . }
       OPTIONAL { ?subject ?predicate dbpedia:The_Matrix . }
}

but some popular RDF databases really can't handle OPTIONAL very performantly yet, and will die.

Kristian
  • 21,204
  • 19
  • 101
  • 176
3

Your are right that is not a valid SPARQL. The closest thing to your OR is UNION. And, there is no need for the AND operator, every triple pattern is by default a join not a union.

For what you are trying is better to use a FILTER, like this example:

CONSTRUCT  { ?subject ?predicate ?object }
WHERE      { ?subject ?predicate ?object . 
             FILTER (  ?subject = <urn:your_uri> || ?object = <urn:your_uri>)
           } 

In some systems, for large knowledge bases, this query can be very expensive. And also if your database contains bNodes this query won't get the description of those nodes, it will get just the internal code. For most cases, running a DESCRIBE manually can't be accomplished with a single query and you'll have to implement some recursive logic in order to get all the information that describes a URI.

Manuel Salvadores
  • 16,287
  • 5
  • 37
  • 56
  • thanks for the answer. All the blank nodes in my dataset are given a URI (in URN syntax) though, so i can still recursively fetch data using the URI to get further information about the resource. – Jeffrey04 Jun 08 '11 at 13:01
  • not sure if this is standard or something, but the 'OR' in FILTER() should be replaced with '||', works for Redland – Jeffrey04 Jun 08 '11 at 13:42
  • for some reason, at least for redland, separating this statement into 2 statements: CONSTRUCT { <..> ?p ?o } WHERE { <..> ?p ?o } and CONSTRUCT { ?s ?p <..> } WHERE { ?s ?p <..> } returns result much faster :/ – Jeffrey04 Jun 15 '11 at 04:01