How to build SPARQL queries in java?
Asked Answered
F

8

11

Is there a library, which is able to build SPARQL queries programmatically like the CriteriaBuilder in JPA or to build the queries like with a PreparedStatement for SQL?

Similar (for SQL): Cleanest way to build an SQL string in Java

Foreleg answered 30/8, 2011 at 21:44 Comment(0)
E
7

You can build queries programmatically in Jena using two methods: syntax or algebra. There's an introduction in the jena wiki.

Using the algebra you'd do something like:

Op op;
BasicPattern pat = new BasicPattern();                 // Make a pattern
pat.add(pattern);                                      // Add our pattern match
op = new OpBGP(pat);                                   // Make a BGP from this pattern
op = OpFilter.filter(e, op);                           // Filter that pattern with our expression
op = new OpProject(op, Arrays.asList(Var.alloc("s"))); // Reduce to just ?s
Query q = OpAsQuery.asQuery(op);                       // Convert to a query
q.setQuerySelectType();                                // Make is a select query

(taken from the wiki page)

It's not CriteriaBuilder (nor was it intended to be), but is some of the way there. You OpJoin rather than AND, OpUnion when you want to OR, etc. The pain points are expressions in my experience: you probably want to parse them from a string.

Era answered 30/8, 2011 at 22:15 Comment(0)
F
7

The recent versions of Jena have added a StringBuilder style API for building query/update strings and parameterizing them if desired.

This class is called ParameterizedSparqlString, here's an example of using it to create a query:

ParameterizedSparqlString queryStr = new ParameterizedSparqlString();
queryStr.setNSPrefix("sw", "http://skunkworks.example.com/redacted#");
queryStr.append("SELECT ?a ?b ?c ?d");
queryStr.append("{");
queryStr.append("   ?rawHit sw:key");
queryStr.appendNode(someKey);
queryStr.append(".");
queryStr.append("  ?rawHit sw:a ?a .");
queryStr.append("  ?rawHit sw:b ?b .");
queryStr.append("  ?rawHit sw:c ?c . ");
queryStr.append("  ?rawHit sw:d ?d .");
queryStr.append("} ORDER BY DESC(d)");

Query q = queryStr.asQuery();

Disclaimer - I'm the developer who contributed this functionality to Jena

See What's the best way to parametize SPARQL queries? for more discussion on doing this across various APIs.

Find answered 7/12, 2012 at 19:57 Comment(0)
D
4

I implemented SPARQL Java - a kind of DSL for writing SPARQL queries in Java.

It solves the problem with IDE's auto formatting of concatenated SPARQL query strings and things like that.

As for example:

String shortQuery = Q.prefix("books", "http://example.org/books#")
            .select("?book ?authorName", new where() {
                {
                    $("?book books:author ?author");
                    $("?author books:authorName ?authorName");
                }
            }).get();
Disinclined answered 6/3, 2014 at 18:42 Comment(0)
A
3

I recently started to use Sesame query builder. It looks promising except it doesn't provide much documentation and I struggled to find examples. Here is simple sample which may help you to get started:

ParsedTupleQuery query = QueryBuilderFactory
            .select("pubProperty", "pubPropertyValue")
                .group()
                    .atom(cmResource(resourceId), LinkPublicationsTransformation.REFERENCE_URI, "pubUri")
                    .atom("pubUri", "pubProperty", "pubPropertyValue")
                    .filter(isLiteral("pubPropertyValue"))
                .closeGroup()
            .query();

Just note that isLiteral and cmResource are my own little static helper classes. isLiteral stands for new IsLiteral(new Var("...")) for example where the latter one create URI with my heavily used prefix.

You might be then also interested in SPARQLQueryRenderer which can turn ParsedQuery into String which may be convenient for further usage.

If you end up using String(Builder) approach what I discourage you to do have at least a look on RenderUtils from sesame-queryrendered which has all the convenient methods to add < > around URIs, escape special characters etc.

Alvy answered 14/4, 2016 at 11:13 Comment(1)
This answer is somewhat out of date: this QueryBuilder is now obsolete and has been replaced by the RDF4J SparqlBuilder instead - see https://mcmap.net/q/969360/-how-to-build-sparql-queries-in-javaTerchie
T
2

The Eclipse RDF4J framework (the successor of Sesame) offers a Repository API which is somewhat similar to JDBC - it allows you to create a prepared Query object and inject variable bindings before executing it:

String query = "SELECT * WHERE {?X ?P ?Y }";
TupleQuery preparedQuery = conn.prepareQuery(QuerLanguage.SPARQL, query);
preparedQuery.setBinding("X", someValue);
...
TupleQueryResult result = preparedQuery.evaluate();

In addition, RDF4J has a SparqlBuilder (originally known as spanqit) - a Java DSL for SPARQL which allows you to create SPARQL queries in code like this:

query.prefix(foaf).select(name)
    .where(x.has(foaf.iri("name"), name))
    .orderBy(name)
    .limit(5)
    .offset(10);
Terchie answered 5/9, 2011 at 1:58 Comment(0)
F
1

I have just released a beta project to do just this, called Spanqit.

I strove for readability and an intuitive interface, for example, here is some example Spanqit syntax for creating a query:

query.prefix(foaf).select(name)
    .where(x.has(foaf.iri("name"), name))
    .orderBy(name)
    .limit(5)
    .offset(10);

Check it out, and feel free to comment and suggest improvements!

Flowering answered 10/11, 2014 at 4:44 Comment(3)
Any luck? I'd love some feedback!Flowering
Not until now, but thanks for the reminder. I will test it soonForeleg
This project has been adopted by the Eclipse Foundation project RDF4J, check out documentation here: docs.rdf4j.org/sparqlbuilderFlowering
W
1

Jena provides a QueryBuilder in the Extras package.

https://jena.apache.org/documentation/extras/querybuilder/index.html

It does what you want.

Wanyen answered 6/1, 2015 at 21:11 Comment(0)
P
0

You can use the Jena Semantic Framework (SPARQL documentation). Also take a look at this related question. Sadly, its syntax is closer to a SQL PreparedStatement than to the JPA.

Portingale answered 30/8, 2011 at 21:55 Comment(3)
but the syntax used on the linked question is the thing i want to avoidForeleg
Ok. I misunderstood your question. I've found other links talking about a library called "Empire" that is a JPA-like interface that uses SPARQL under the covers (weblog.clarkparsia.com/2010/01/11/empire-05) but I've not been able to find the source code at github.Portingale
I've finally found it at github.com/mhgrove/Empire but I've never used it before. I hope it fits your needs, despite it seems hard to start using it: weblog.clarkparsia.com/2010/05/07/…Portingale

© 2022 - 2024 — McMap. All rights reserved.