How to build SPARQL queries in java?

后端 未结 8 1583
囚心锁ツ
囚心锁ツ 2021-02-01 10:19

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 PreparedStateme

相关标签:
8条回答
  • 2021-02-01 10:55

    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);
    
    0 讨论(0)
  • 2021-02-01 10:57

    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.

    0 讨论(0)
  • 2021-02-01 10:59

    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!

    0 讨论(0)
  • 2021-02-01 11:06

    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.

    0 讨论(0)
  • 2021-02-01 11:08

    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.

    0 讨论(0)
  • 2021-02-01 11:09

    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.

    0 讨论(0)
提交回复
热议问题