0

I am trying to construct a long query using the rdf4j library and would like to use the count function that is available with SPARQL.

The original SPARQL query looks like this:

SELECT (COUNT(?letter) AS ?count) WHERE { \
    ?letter a :Letter . \
    ?letter :writtenBy :John . \
    ?letter :writtenOn ?date . \
    FILTER(?date > NOW() && }     

This is what I have so far using the rdf4j library

GraphPattern longPattern = GraphPatterns.tp(letter, ex.iri("a"), ex.iri("Letter")).
                and(GraphPatterns.tp(letter, ex.iri("writtenBy"), ex.iri("John"))).
                and(GraphPatterns.tp(letter, ex.iri("writtenOn"), date));

How can I implement the Count and use the NOW() functionality of sparql? I know there is a filter method but I don't know how to use the NOW() with it. All of the variables (letter, date) and a select query have been initialised within java using SparqlBuilder.

vaishalir
  • 55
  • 3
  • Why do you have `FILTER(?date > NOW() && } ` and not just `FILTER(?date > NOW())}`? – Valerio Cocchi May 18 '21 at 15:00
  • Also, it would be helpful if you elaborated on what error you're getting with your current method. – Valerio Cocchi May 18 '21 at 15:01
  • filter functions take expressions, you should have a look at section 5 in https://rdf4j.org/documentation/tutorials/sparqlbuilder/ - maybe, `now()` isn't among the existing expressions, if not it should be among the functions, see `SparqlFunction` enum – UninformedUser May 18 '21 at 15:36

1 Answers1

3

In the RDF4J SparqlBuilder, functions are created using org.eclipse.rdf4j.sparqlbuilder.constraint.Expressions static methods. For example, to create the BNode() function, you just do this:

Expression bnodeFunc = Expressions.bnode();

Similarly, for the COUNT aggregate function:

Expression countAgg = Expressions.count(letter);

and to use that in your SELECT clause, you'd do something like this:

Variable count = SparqlBuilder.var("count");
Projection select = SparqlBuilder.select(countAgg.as(count));

As for the now() function: Annoyingly, the list of function factory methods in Expressions is incomplete: for now() there is no direct static factory method. However, you can use the general Expressions.function method to create it, as follows:

Expression nowFunc = Expressions.function(SparqlFunction.NOW);

By the way, your current graph pattern can be simplified quite a bit. Instead of this:

GraphPattern longPattern = GraphPatterns.tp(letter, default.iri("a"), default.iri("Letter")).
                and(GraphPatterns.tp(letter, default.iri("writtenBy"), legislate.iri("John"))).
                and(GraphPatterns.tp(letter, legislate.iri("writtenOn"), date));

Do this:

TriplePattern longPattern = letter.isA(ex.iri("Letter"))
        .andHas(ex.iri("writtenBy"), legislate.iri("John"))
        .andHas(legislate.iri("writtenOn"), date);

This is easier to read and shorter, and secondly, your use of default.iri("a") was incorrect (as an aside I don't even know how you have a Java variable called default because that's a reserved keyword and should result in a compilation error - so I've replaced with ex here).

Putting it all together you'd get something like this:

SelectQuery select = Queries.SELECT()
        .prefix(ex)
        .prefix(legislate)
        .select(countAgg.as(count))
        .where(GraphPatterns.and(longPattern)
                .filter(Expressions.gt(date, nowFunc)));
Jeen Broekstra
  • 21,642
  • 4
  • 51
  • 73