1

I am using an RDF4J native triplestore where several named graphs/models are stored. In my Java program, I am trying to retrieve a partial graph out of a named graph by using the SPARQL CONSTRUCT query form. The partial graph should be identified by a specific integer value.

One of my stored named graphs looks like this, for example:

@prefix nif: <http://persistence.uni-leipzig.org/nlp2rdf/ontologies/nif-core#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix app: <http://example.org/> .
@prefix onto: <http://example.org/ontology/> .

app:context#char=0,54 a nif:Context , nif:RFC5147String , nif:String ;
    nif:beginIndex "0"^^xsd:int ;
    nif:endIndex "54"^^xsd:int ;
    nif:isString "Barack Obama lives in Washington. He studied at Harvard" .

app:sentence#char=0,31 a nif:RFC5147String , nif:String , nif:Sentence ;
    onto:index "0"^^xsd:int ;
    nif:beginIndex "0"^^xsd:int ;
    nif:endIndex "31"^^xsd:int ;
    onto:entity app:entity#char=0,12 , app:entity#char=22,30 ;
    nif:referenceContext app:context#char=0,54 ;
    nif:nextSentence app:sentence#char=32,54 ;
    nif:anchorOf "Barack Obama lives in Washington." .

app:sentence#char=32,54 a nif:RFC5147String , nif:String , nif:Sentence ;
    onto:index "1"^^xsd:int ;
    nif:beginIndex "32"^^xsd:int ;
    nif:endIndex "54"^^xsd:int ;
    onto:entity app:entity#char=46,53 ;
    nif:referenceContext app:context#char=0,54 ;
    nif:previousSentence app:sentence#char=0,31 ;
    nif:anchorOf "He studied at Harvard." .

app:entity#char=0,12 a nif:RFC5147String , nif:String , nif:Phrase ;
    nif:beginIndex "0"^^xsd:int ;
    nif:endIndex "12"^^xsd:int ;
    onto:type "PERSON" ;
    nif:referenceContext app:context#char=0,54 ;
    nif:sentence app:sentence#char=0,31 ;
    nif:anchorOf "Barack Obama" .       

app:entity#char=22,30 a nif:RFC5147String , nif:String , nif:Phrase ;
    nif:beginIndex "22"^^xsd:int ;
    nif:endIndex "30"^^xsd:int ;
    onto:type "LOCATION" ;
    nif:referenceContext app:context#char=0,54 ;
    nif:sentence app:sentence#char=0,31 ;
    nif:anchorOf "Washington" .

app:entity#char=46,53 a nif:RFC5147String , nif:String , nif:Phrase ;
    nif:beginIndex "46"^^xsd:int ;
    nif:endIndex "53"^^xsd:int ;
    onto:type "ORGANIZATION" ;
    nif:referenceContext app:context#char=0,54 ;
    nif:sentence app:sentence#char=32,54 ;
    nif:anchorOf "Harvard" .

The above graph describes two sentences that have been annotated with NLP tools. I want to query a subgraph that represents one of these sentences including the context, the sentence itself and all the entities of that particular sentence.

Every sentence has an index with the predicate onto:index, which I want to use in order to identify a specific sentence. The entities belonging to a sentence are identified by onto:entity.

So, the desired subgraph should consist of the subjects app:context#char=0,54, app:sentence#char=0,31, app:entity#char=0,12 and app:entity#char=22,30 with all their respective predicates and objects. Therefore, it should not contain the subjects app:sentence#char=32,54 and app:entity#char=46,53.

My SPARQL query looks like this so far:

PREFIX nif: <http://persistence.uni-leipzig.org/nlp2rdf/ontologies/nif-core#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX app: <http://example.org/location#>
PREFIX onto: <http://example.org/ontology/>

CONSTRUCT {
    ?s ?p ?o .
}

WHERE {
    GRAPH app:12345 {
        ?s onto:index sentenceIndex .
    }
}

In Java it looks like this:

String nif: "http://persistence.uni-leipzig.org/nlp2rdf/ontologies/nif-core#";
String xsd: "http://www.w3.org/2001/XMLSchema#";
String app = "http://example.org/location#" + modelID;
String onto = "http://example.org/ontology/";

    String sparqlQuery = "PREFIX nif: <" + nif + "> \n";
    sparqlQuery += "PREFIX xsd: <" + xsd + "> \n";
    sparqlQuery += "PREFIX onto: <" + onto + "> \n";
    sparqlQuery += "CONSTRUCT { \n";
    sparqlQuery += "    ?s ?p ?o . \n";
    sparqlQuery += "} \n";
    sparqlQuery += "WHERE { \n";
    sparqlQuery += "    GRAPH <" + app + "> { \n";
    sparqlQuery += "        ?s onto:index " + sentenceIndex + " . \n";
    sparqlQuery += "    } \n";
    sparqlQuery += "}";

The sentenceIndex expression is a Java int variable that delivers the actual onto:index value. app:location#12345 is the superior named graph.

For test purposes, the above query should initially just return the whole sentence subject by the given index without the context or entities. But even this easy task fails. It just returns an empty RDF4J model.

Now, what is the correct SPARQL query in order to get the desired subgraph identified by the onto:index predicate?

I am not familiar with SPARQL, so any help is greatly appreciated. Thanks in advance!

phly
  • 185
  • 1
  • 12
  • This query is syntactically incorrect, and won't return an empty model - instead the query will fail with a syntax error (caused by full stops behind your prefix declarations). It's probably just a copy-paste error on your part, and easily fixed, but for future reference, please keep in mind to test the exact code you're posting on SO. – Jeen Broekstra Feb 07 '17 at 03:17
  • I am sorry, this was indeed a copy & paste error. I have edited my post and added the actual Java code, additionally. This code has no compile error, but returns an empty model. – phly Feb 07 '17 at 09:40

2 Answers2

3
  1. Prefixes are not delimited by dots in SPARQL, i.e. the query should not compile in RDF4J

  2. Why do you put the prefixed graph URI into angle brackets? Either you use

    1. the full URI <http://example.org/location#12345> or
    2. you change the namespace declaration of app and use the prefixed URI app:12345
PREFIX  app:  <http://example.org/location#>
PREFIX  xsd:  <http://www.w3.org/2001/XMLSchema#>
PREFIX  nif:  <http://persistence.unileipzig.org/nlp2rdf/ontologies/nif-core#>
PREFIX  onto: <http://example.org/ontology/>

CONSTRUCT 
  { 
    ?s ?p ?o .
  }
WHERE
  { GRAPH app:12345
      { ?s  onto:index  sentenceIndex }
  }
UninformedUser
  • 8,397
  • 1
  • 14
  • 23
  • I am sorry, this was a copy & paste error caused by a mixture of my actual Java code and the turtle data. I have edited my original post. But it still does not work and just returns an empty model. – phly Feb 07 '17 at 09:42
  • Have you also changed how you use the graph URI? Your Java code produces `GRAPH ` and in your question you say that the graph is `app:location#12345` – UninformedUser Feb 07 '17 at 12:50
  • Yes, I have changed it in my example. But it should not make any difference semantic-wise, doesn't it? – phly Feb 09 '17 at 12:29
1

to make the task easier I would recommend you to not use prefixes at all at the moment. Try first to see if the following construct query works:

CONSTRUCT {
    ?s ?p ?o .
}

WHERE {
    GRAPH <http://example.org/location#12345> {
        ?s <http://example.org/ontology/index> 0 .
    }
}

If that does not work, check if the data really, really, 100% is in the graph "http://example.org/location#12345" by using the following query:

SELECT * 
WHERE {
  ?s ?p ?o 

  optional{
  GRAPH ?g {
    ?s ?p ?o
  }
 }
}

This query shows you all your data, and on what graph the data is on. By using this query, you can also check, if the predicate you query for (index) is correct or not.

Hope this helps you finding your problem, and happy SPARQLing!

ChristophE
  • 760
  • 1
  • 9
  • 21