I want to get the latitude and longitude of a place whose name I already know by
PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
PREFIX dbo: <http://dbpedia.org/ontology/>
SELECT * WHERE {
?s a dbo:Place .
?s geo:lat ?lat .
?s geo:long ?long .
}
where the name of the place (?s) is something like Graves Park.
How would one go about implementing the same in Jena where the name of the place might vary?
You can use Jena's ARQ to execute queries against remote SPARQL endpoints. The process is described in ARQ — Querying Remote SPARQL Services.
Using ParameterizedSparqlStrings in SELECT queries
To do this for different places that you might not know until it is time to execute the query, you can use a ParameterizedSparqlString to hold the query and then inject the value(s) once you have them. Here's an example. The query is the one you provided. I put it into a ParameterizedSparqlString, and then used setIri to set ?s to http://dbpedia.org/resource/Mount_Monadnock.
import com.hp.hpl.jena.query.ParameterizedSparqlString;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.query.ResultSetFormatter;
public class DBPediaQuery {
public static void main( String[] args ) {
final String dbpedia = "http://dbpedia.org/sparql";
final ParameterizedSparqlString queryString
= new ParameterizedSparqlString(
"PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>"+
"PREFIX dbo: <http://dbpedia.org/ontology/>" +
"SELECT * WHERE {" +
" ?s a dbo:Place ." +
" ?s geo:lat ?lat ." +
" ?s geo:long ?long ." +
"}" );
queryString.setIri( "?s", "http://dbpedia.org/resource/Mount_Monadnock");
QueryExecution exec = QueryExecutionFactory.sparqlService( dbpedia, queryString.toString() );
ResultSet results = exec.execSelect();
ResultSetFormatter.out( System.out, results );
}
}
The results printed by this are:
--------------------------------------------------------------------------------------------------------------
| lat | long |
==============================================================================================================
| "42.8608"^^<http://www.w3.org/2001/XMLSchema#float> | "-72.1081"^^<http://www.w3.org/2001/XMLSchema#float> |
--------------------------------------------------------------------------------------------------------------
Once you have the ResultSet, you can iterate through the rows of the solution and extract the values. The values here are Literals, and from a Literal you can extract the lexical form (the string value), or the value as the corresponding Java type (in the case of numbers, strings, booleans, &c.). You could do the the following to print the latitude and longitude instead of using the ResultSetFormatter:
while ( results.hasNext() ) {
QuerySolution solution = results.next();
Literal latitude = solution.getLiteral( "?lat" );
Literal longitude = solution.getLiteral( "?long" );
String sLat = latitude.getLexicalForm();
String sLon = longitude.getLexicalForm();
float fLat = latitude.getFloat();
float fLon = longitude.getFloat();
System.out.println( "Strings: " + sLat + "," + sLon );
System.out.println( "Floats: " + fLat + "," + fLon );
}
The output after this change is:
Strings: 42.8608,-72.1081
Floats: 42.8608,-72.1081
Using ParameterizedSparqlStrings in CONSTRUCT queries
Based some of the comments, it may also be useful to use CONSTRUCT queries to save the results from each query, and to aggregate them into a larger model. Here's code that uses a construct query to retrieve the latitude and longitude of Mount Monadnock and Mount Lafayette, and stores them in a single model. (Here we're just using CONSTRUCT WHERE {…}, so the model that is returned is exactly the same as the part of the graph that matched. You can get different results by using CONSTRUCT {…} WHERE {…}.)
import com.hp.hpl.jena.query.ParameterizedSparqlString;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
public class DBPediaQuery {
public static void main( String[] args ) {
final String dbpedia = "http://dbpedia.org/sparql";
final ParameterizedSparqlString queryString
= new ParameterizedSparqlString(
"PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>"+
"PREFIX dbo: <http://dbpedia.org/ontology/>" +
"CONSTRUCT WHERE {" +
" ?s a dbo:Place ." +
" ?s geo:lat ?lat ." +
" ?s geo:long ?long ." +
"}" );
Model allResults = ModelFactory.createDefaultModel();
for ( String mountain : new String[] { "Mount_Monadnock", "Mount_Lafayette" } ) {
queryString.setIri( "?s", "http://dbpedia.org/resource/" + mountain );
QueryExecution exec = QueryExecutionFactory.sparqlService( dbpedia, queryString.toString() );
Model results = exec.execConstruct();
allResults.add( results );
}
allResults.setNsPrefix( "geo", "http://www.w3.org/2003/01/geo/wgs84_pos#" );
allResults.setNsPrefix( "dbo", "http://dbpedia.org/ontology/" );
allResults.setNsPrefix( "dbr", "http://dbpedia.org/resource/" );
allResults.write( System.out, "N3" );
}
}
The output shows triples from both queries:
#prefix dbr: <http://dbpedia.org/resource/> .
#prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> .
#prefix dbo: <http://dbpedia.org/ontology/> .
dbr:Mount_Lafayette
a dbo:Place ;
geo:lat "44.1607"^^<http://www.w3.org/2001/XMLSchema#float> ;
geo:long "-71.6444"^^<http://www.w3.org/2001/XMLSchema#float> .
dbr:Mount_Monadnock
a dbo:Place ;
geo:lat "42.8608"^^<http://www.w3.org/2001/XMLSchema#float> ;
geo:long "-72.1081"^^<http://www.w3.org/2001/XMLSchema#float> .
Related
When i run this query on dbpedia.org
SELECT DISTINCT ?resource ?label ?location
WHERE
{
<http://dbpedia.org/resource/New_York_City> geo:geometry ?sourcegeo .
?resource geo:geometry ?location ;
rdfs:label ?label .
FILTER( bif:st_intersects( ?location, ?sourcegeo, 20 ) ) .
FILTER( lang( ?label ) = "en" )
}
it is producing results fine but same query gives me error when using java jena api.
String s2 = "SELECT DISTINCT ?resource ?label ?location \r\n" +
"WHERE \r\n" +
" { \r\n" +
" <http://dbpedia.org/resource/New_York_City> geo:geometry ?sourcegeo . \r\n" +
" ?resource geo:geometry ?location ; \r\n" +
" rdfs:label ?label . \r\n" +
" FILTER( bif:st_intersects( ?location, ?sourcegeo, 20 ) ) . \r\n" +
" FILTER( lang( ?label ) = \"en\" ) \r\n" +
" }\r\n" +
"";
Query query = QueryFactory.create(s2); //s2 = the query above
QueryExecution qExe = QueryExecutionFactory.sparqlService( "http://dbpedia.org/sparql", query );
ResultSet results = qExe.execSelect();
ResultSetFormatter.out(System.out, results, query) ;
it gives me the following errors
Exception in thread "main" org.apache.jena.query.QueryParseException: Line 4, column 49: Unresolved prefixed name: geo:geometry
at org.apache.jena.sparql.lang.ParserBase.throwParseException(ParserBase.java:521)
at org.apache.jena.sparql.lang.ParserBase.resolvePName(ParserBase.java:286)
at org.apache.jena.sparql.lang.sparql_11.SPARQLParser11.PrefixedName(SPARQLParser11.java:4857)
at org.apache.jena.sparql.lang.sparql_11.SPARQLParser11.iri(SPARQLParser11.java:4841) and it goes on
DBPedia has a number of Predefined Namespace Prefixes, which includes
PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>,
which Jena does not have. Hence you have to specify it for use Jena before your SELECT. I.e.
String s2 = "PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>\r\n" +
"SELECT DISTINCT ?resource ?label ?location \r\n" +
... etc
Below SPARQL execdescribe query giving me only two prefixes as output while running with Jena query but when I run this query on virtuoso SPARQL endpoint it's giving perfect output.
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX db: <http://dbpedia.org/ontology/>
PREFIX prop: <http://dbpedia.org/property/>
DESCRIBE ?movie ?author ?genre
WHERE {
?movie rdf:type db:Film ;
prop:author ?author ;
prop:genre ?genre .
}
LIMIT 2
OFFSET 0
When I run with Jena I am getting only two line output like this,
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
Below is my code which I am using but with some query its working fine,
String queryString = "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>" +
"PREFIX db: <http://dbpedia.org/ontology/> " +
"PREFIX prop: <http://dbpedia.org/property/>" +
"DESCRIBE ?movie ?author ?genre" +
"WHERE { " +
"?movie rdf:type db:Film ;" +
"prop:author ?author ;" +
"prop:genre ?genre ." +
"}" +
"LIMIT 2" +
"OFFSET 0";
QueryExecution qexec = QueryExecutionFactory.sparqlService("http://localhost:8890/sparql", queryString);
Model results = qexec.execDescribe();
results.write(System.out,"TTL");
Its perfectly giving me output on virtuoso SPARQL end point.
below is screen shot,
As suggested in comments by #AKSW, There is a space issue in the query. So after edited my query, it will perfectly work fine.
I am using the Jena Java framework for querying DBpedia end point using SPARQL, to get the type for all points of interest in German cities. I am facing no issue for places that have English DBpedia entries. But, when it comes to place names to be queried from the German DBpedia endpoint (http://de.dbpedia.org/resource/Schloß_Nymphenburg), this query returns no result. This problem is also mentioned over here (http://mail-archives.apache.org/mod_mbox/jena-users/201110.mbox/%3C4E877C8A.4050705#apache.org%3E). Even after referring to this, I am unable to solve the problem. I don't know how to work with QueryEngineHTTP. I am adding two code snippets - one that works (first one - query for Allianz Arena : which has an English entry in DBpedia) and one that doesn't work (second one - for Schloß Nymphenburg, that has a German entry).
This might be a very trivial issue, but I am unable to solve it. Any pointers to a solution would be very very helpful.
Thanks a lot!
Code 1 - working :
String service = "http://dbpedia.org/sparql";
final ParameterizedSparqlString query = new ParameterizedSparqlString(
"PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>" +
"PREFIX dbo: <http://dbpedia.org/ontology/>" +
"PREFIX dcterms: <http://purl.org/dc/terms/>" +
"SELECT * WHERE {" +
"?s geo:lat ?lat ." +
"?s geo:long ?long ." +
"?s dcterms:subject ?sub}");
query.setIri("?s", "http://dbpedia.org/resource/Allianz_Arena");
QueryExecution qe = QueryExecutionFactory.sparqlService(service, query.toString());
ResultSet results = qe.execSelect();
ResultSetFormatter.out(System.out, results);
Code 2 - not working :
String service = "http://dbpedia.org/sparql";
final ParameterizedSparqlString query = new ParameterizedSparqlString(
"PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>" +
"PREFIX dbo: <http://dbpedia.org/ontology/>" +
"PREFIX dcterms: <http://purl.org/dc/terms/>" +
"SELECT * WHERE {" +
"?s geo:lat ?lat ." +
"?s geo:long ?long ." +
"?s dcterms:subject ?sub}");
query.setIri("?s", "http://de.dbpedia.org/resource/Schloß_Nymphenburg");
QueryExecution qe = QueryExecutionFactory.sparqlService(service, query.toString());
ResultSet results = qe.execSelect();
ResultSetFormatter.out(System.out, results);
I don't think this is an issue with jena at all. Trying:
SELECT * WHERE {
<http://de.dbpedia.org/resource/Schloß_Nymphenburg> ?p ?o }
at http://dbpedia.org/sparql I get no results: try it yourself.
SELECT * WHERE {
<http://de.dbpedia.org/resource/Schloss_Nymphenburg> ?p ?o }
by contrast returns something, even if it's just a bunch of cross links.
I'm using Jena to make a SPARQL query to search for all a document's properties by its subject. But the documents can have more than one subject, and when I do the search, it doesn't return me all the documents' properties, including all the documents' subjects, but even if it has 3 subjects (for example) it returns me all the documents properties + only the subject I set at FILTER.
I'd like to have as a return all the properties from the found document + all the subjects (that belong to the found document) and not only the one at FILTER.
Query (this.subject is a variable that has its value set in a JSF page):
String queryString = "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> " +
"PREFIX dc: <http://purl.org/dc/elements/1.1/> " +
"PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT ?document ?subject" +
" ?title ?description ?language WHERE { " +
"?document dc:title ?title." +
"?document dc:subject ?subject." +
"?document dc:description ?description." +
"?document dc:language ?language." +
"FILTER ( regex(?subject, replace( \"" + this.subject + "\", ' ', '|' ), 'i' )). }";
Thank you!
You likely want to use a sub-query to restrict to the documents matching the FILTER and then select the rest of the stuff you are actually interesting in e.g.
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX dc : <http://purl.org/dc/elements/1.1/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?document ?subject ?title ?description ?language
WHERE
{
{
SELECT ?document
WHERE
{
?document dc:subject ?subject .
FILTER(REGEX(?subject, REPLACE("search term", " ", "|"), "i"))
}
}
?document dc:title ?title ;
dc:description ?description ;
dc:subject ?subject ;
dc:language ?language .
}
Note that this is still going to give you a row for each document-subject combination so if you have a document with 3 subjects you'll get three rows for that document. If you want to combine documents into a single row then you can use GROUP BY and then a GROUP_CONCAT aggregate, there are other questions already on Stack Overflow that detail how to do that.
Notes
Also note that using simple string concatenation to inject constants into your query is ill advised, take a look at Jena's ParameterizedSparqlString for a more user friendly and SPARQL injection proof API for building queries.
I am trying to extract labels from DBpedia for some persons. I am partially successful now, but I got stuck in the following problem. The following code works.
public class DbPediaQueryExtractor {
public static void main(String [] args) {
String entity = "Aharon_Barak";
String queryString ="PREFIX dbres: <http://dbpedia.org/resource/> SELECT * WHERE {dbres:"+ entity+ "<http://www.w3.org/2000/01/rdf-schema#label> ?o FILTER (langMatches(lang(?o),\"en\"))}";
//String queryString="select * where { ?instance <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://xmlns.com/foaf/0.1/Person>; <http://www.w3.org/2000/01/rdf-schema#label> ?o FILTER (langMatches(lang(?o),\"en\")) } LIMIT 5000000";
QueryExecution qexec = getResult(queryString);
try {
ResultSet results = qexec.execSelect();
for ( ; results.hasNext(); )
{
QuerySolution soln = results.nextSolution();
System.out.print(soln.get("?o") + "\n");
}
}
finally {
qexec.close();
}
}
public static QueryExecution getResult(String queryString){
Query query = QueryFactory.create(queryString);
//VirtuosoQueryExecution vqe = VirtuosoQueryExecutionFactory.create (sparql, graph);
QueryExecution qexec = QueryExecutionFactory.sparqlService("http://dbpedia.org/sparql", query);
return qexec;
}
}
However, when the entity contains brackets, it does not work. For example,
String entity = "William_H._Miller_(writer)";
leads to this exception:
Exception in thread "main" com.hp.hpl.jena.query.QueryParseException: Encountered " "(" "( "" at line 1, column 86.`
What is the problem?
It took some copying and pasting to see what exactly was going on. I'd suggest that you put newlines in your query for easier readability. The query you're using is:
PREFIX dbres: <http://dbpedia.org/resource/>
SELECT * WHERE
{
dbres:??? <http://www.w3.org/2000/01/rdf-schema#label> ?o
FILTER (langMatches(lang(?o),"en"))
}
where ??? is being replaced by the contents of the string entity. You're doing absolutely no input validation here to ensure that the value of entity will be legal to paste in. Based on your question, it sounds like entity contains William_H._Miller_(writer), so you're getting the query:
PREFIX dbres: <http://dbpedia.org/resource/>
SELECT * WHERE
{
dbres:William_H._Miller_(writer) <http://www.w3.org/2000/01/rdf-schema#label> ?o
FILTER (langMatches(lang(?o),"en"))
}
You can paste that into the public DBpedia endpoint, and you'll get a similar parse error message:
Virtuoso 37000 Error SP030: SPARQL compiler, line 6: syntax error at 'writer' before ')'
SPARQL query:
define sql:big-data-const 0
#output-format:text/html
define sql:signal-void-variables 1 define input:default-graph-uri <http://dbpedia.org> PREFIX dbres: <http://dbpedia.org/resource/>
SELECT * WHERE
{
dbres:William_H._Miller_(writer) <http://www.w3.org/2000/01/rdf-schema#label> ?o
FILTER (langMatches(lang(?o),"en"))
}
Better than hitting DBpedia's endpoint with bad queries, you can also use the SPARQL query validator, which reports for that query:
Syntax error: Lexical error at line 4, column 34. Encountered: ")" (41), after : "writer"
In Jena, you can use the ParameterizedSparqlString to avoid these sorts of issues. Here's your example, reworked to use a parameterized string:
import com.hp.hpl.jena.query.ParameterizedSparqlString;
public class PSSExample {
public static void main( String[] args ) {
// Create a parameterized SPARQL string for the particular query, and add the
// dbres prefix to it, for later use.
final ParameterizedSparqlString queryString = new ParameterizedSparqlString(
"PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n" +
"SELECT * WHERE\n" +
"{\n" +
" ?entity rdfs:label ?o\n" +
" FILTER (langMatches(lang(?o),\"en\"))\n" +
"}\n"
) {{
setNsPrefix( "dbres", "http://dbpedia.org/resource/" );
}};
// Entity is the same.
final String entity = "William_H._Miller_(writer)";
// Now retrieve the URI for dbres, concatentate it with entity, and use
// it as the value of ?entity in the query.
queryString.setIri( "?entity", queryString.getNsPrefixURI( "dbres" )+entity );
// Show the query.
System.out.println( queryString.toString() );
}
}
The output is:
PREFIX dbres: <http://dbpedia.org/resource/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT * WHERE
{
<http://dbpedia.org/resource/William_H._Miller_(writer)> rdfs:label ?o
FILTER (langMatches(lang(?o),"en"))
}
You can run this query at the public endpoint and get the expected results. Notice that if you use an entity that doesn't need special escaping, e.g.,
final String entity = "George_Washington";
then the query output will use the prefixed form:
PREFIX dbres: <http://dbpedia.org/resource/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT * WHERE
{
dbres:George_Washington rdfs:label ?o
FILTER (langMatches(lang(?o),"en"))
}
This is very convenient, because you don't have to do any checking about whether your suffix, i.e., entity, has any characters that need to be escaped; Jena takes care of that for you.