Parameterized SPARQL query with JENA
Asked Answered
O

2

7

I'm trying to build a small semantic web application using Jena framework, JSP and JAVA. I have a remote SPARQL endpoint and I've already written a simple query which works fine but now I need to use some parameters. Here is my code so far:

final static String serviceEndpoint = "http://fishdelish.cs.man.ac.uk/sparql/";

String comNameQuery = 
        "PREFIX fd: <http://fishdelish.cs.man.ac.uk/rdf/vocab/resource/> " +
        "SELECT ?name ?language ?type" +
        "WHERE { ?nameID fd:comnames_ComName ?name ;" +
        "fd:comnames_Language ?language ;" +
        "fd:comnames_NameType ?type ." +
        "}";

Query query = QueryFactory.create(comNameQuery);  
QueryExecution qe = QueryExecutionFactory.sparqlService(serviceEndpoint,query);

try {
    ResultSet rs = qe.execSelect();
    if ( rs.hasNext() ) {
        System.out.println(ResultSetFormatter.asText(rs));
    }
} 
catch(Exception e) { 
    System.out.println(e.getMessage());
}
finally {
    qe.close();
}

What I want to do is to parameterized ?name. I'm new to Jena and I'm not really sure how to use parameters in a SPARQL query. I would appreciate it if someone could help me with this.

Orthographize answered 15/3, 2012 at 23:21 Comment(2)
Duplicated on answers.semanticweb.com/questions/15237/…Hochman
@Orthographize Did any of these answers end up working for you? If one did, you should accept it to let others know that it was useful.Ferrol
H
6

If you just want to restrict a variable to have a certain value for local queries you can do so with an overload of the QueryFactory.create() method which takes a QuerySolutionMap to set value restrictions. Note this doesn't alter your query just restricts the final results so this is not really parameterization.

If you want to actually have true parameterized queries (i.e. substitute variables for constants) then there are a couple of ways to do this depending on your version of ARQ.

Using any current release (up to 2.9.0) the only way to do it is string concatenation i.e. instead of having ?name in your query you would just insert the value you want e.g. "Bob"

Using the latest trunk (2.9.1-SNAPSHOT onwards) there is a new ParameterizedSparqlString class which makes this much more user friendly e.g.

ParameterizedSparqlString queryStr = new ParameterizedSparqlString(comNameQuery);
queryStr.setLiteral("name", "Bob");

Query query = QueryFactory.create(queryStr.toString());

And in fact you can simplify your code further since ParameterizedSparqlString has a StringBuffer style interface and can be used to build your query bit by bit and includes useful functionality like prepending prefixes to your query.

The advantage of this new method is that it provides a more generic way of doing parameterized queries that can also be used with updates and is usable for preparing remote queries which the existing methods do not cover.

Hochman answered 16/3, 2012 at 0:28 Comment(2)
Thanks Rob I will try what you suggested. What I intend to do is to get an input from the user for e.g. a name and pass this value to ?name in my query. Is there any other framework that offers this function or it is in general better to use than Jena framework?Orthographize
You can probably do the same thing with Sesame but I don't know the details, which framework is best for you will depend on what kinds of things you need to do. If you have further questions not directly related to this answer please ask them as new questions on the site so that they are more widely visibleHochman
C
2

You could try looking into Twinkql. It is a SPARQL-to-Java mapping framework. It uses Jena in the back end, but tries to simplify SPARQL queries and Java binding of the results.

It allows you to define SPARQL queries in xml:

<select id="getNovel" resultMap="novelResultMap">
<![CDATA[
    SELECT ?novel ?author
    WHERE {
        ?novel a <http://dbpedia.org/class/yago/EnglishNovels> ;
            <http://dbpedia.org/property/name> "#{novelName}"@en ;
            <http://dbpedia.org/property/author> ?author .
    }
]]>
</select>

Note the #{novelName} placeholder -- this is where parameters can be passed in at query time.

Also, results can be bound to Java Beans:

<resultMap id="novelResultMap" resultClass="org.twinkql.example.Novel">
    <uniqueResult>novel</uniqueResult>
    <rowMap  var="novel" varType="localName" beanProperty="name" />
    <rowMap var="author" varType="localName" beanProperty="author"/>
</resultMap>

There is an API to call these queries, to pass in parameters, etc. It is much like MyBatis, but for SPARQL instead of SQL.

Cannoneer answered 5/7, 2012 at 3:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.