如何使用 rdf4j 构造长查询

How to construct long queries using rdf4j

我正在尝试使用 rdf4j 库构建一个长查询,并想使用 SPARQL 提供的计数函数。

原始 SPARQL 查询如下所示:

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

这是我目前使用 rdf4j 库的结果

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));

如何实现 Count 和使用 sparql 的 NOW() 功能?我知道有一个过滤方法,但我不知道如何使用 NOW() 。所有变量(字母、日期)和 select 查询都已使用 SparqlBuilder 在 java 内初始化。

在 RDF4J SparqlBuilder 中,函数是使用 org.eclipse.rdf4j.sparqlbuilder.constraint.Expressions 静态方法创建的。例如,要创建 BNode() 函数,您只需这样做:

Expression bnodeFunc = Expressions.bnode();

同样,对于COUNT聚合函数:

Expression countAgg = Expressions.count(letter);

要在 SELECT 子句中使用它,您需要执行以下操作:

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

至于now()函数:烦人的是,Expressions中的函数工厂方法列表不完整:now()没有直接的静态工厂方法。不过可以使用通用的Expressions.function方法来创建,如下:

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

顺便说一下,您当前的图形模式可以简化很多。而不是这个:

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));

这样做:

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

这更容易阅读和缩短,其次,您对 default.iri("a") 的使用不正确(顺便说一句,我什至不知道您如何拥有一个名为 [=25] 的 Java 变量=] 因为这是一个保留关键字,应该会导致编译错误 - 所以我在这里用 ex 替换了)。

把它们放在一起你会得到这样的东西:

SelectQuery select = Queries.SELECT()
        .prefix(ex)
        .prefix(legislate)
        .select(countAgg.as(count))
        .where(GraphPatterns.and(longPattern)
                .filter(Expressions.gt(date, nowFunc)));