ARQ 允许您通过在AggregateRegistry
. 示例代码显示了这是如何完成的。这可用于添加问题中请求的自定义标准差聚合函数。在下面的示例中,Commons Math用于进行计算。
import org.apache.commons.math3.stat.descriptive.SummaryStatistics;
import org.apache.jena.graph.Graph;
import org.apache.jena.query.*;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.sparql.engine.binding.Binding;
import org.apache.jena.sparql.expr.ExprList;
import org.apache.jena.sparql.expr.NodeValue;
import org.apache.jena.sparql.expr.aggregate.Accumulator;
import org.apache.jena.sparql.expr.aggregate.AccumulatorFactory;
import org.apache.jena.sparql.expr.aggregate.AggCustom;
import org.apache.jena.sparql.expr.aggregate.AggregateRegistry;
import org.apache.jena.sparql.function.FunctionEnv;
import org.apache.jena.sparql.graph.NodeConst;
import org.apache.jena.sparql.sse.SSE;
public class StandardDeviationAggregate {
/**
* Custom aggregates use accumulators. One accumulator is created for each group in a query execution.
*/
public static AccumulatorFactory factory = (agg, distinct) -> new StatsAccumulator(agg);
private static class StatsAccumulator implements Accumulator {
private AggCustom agg;
private SummaryStatistics summaryStatistics = new SummaryStatistics();
StatsAccumulator(AggCustom agg) { this.agg = agg; }
@Override
public void accumulate(Binding binding, FunctionEnv functionEnv) {
// Add values to summaryStatistics
final ExprList exprList = agg.getExprList();
final NodeValue value = exprList.get(0).eval(binding, functionEnv) ;
summaryStatistics.addValue(value.getDouble());
}
@Override
public NodeValue getValue() {
// Get the standard deviation
return NodeValue.makeNodeDouble(summaryStatistics.getStandardDeviation());
}
}
public static void main(String[] args) {
// Register the aggregate function
AggregateRegistry.register("http://example/stddev", factory, NodeConst.nodeMinusOne);
// Add data
Graph g = SSE.parseGraph("(graph " +
"(:item1 :hasPrice 13) " +
"(:item2 :hasPrice 15) " +
"(:item3 :hasPrice 20) " +
"(:item4 :hasPrice 30) " +
"(:item5 :hasPrice 32) " +
"(:item6 :hasPrice 11) " +
"(:item7 :hasPrice 16))");
Model m = ModelFactory.createModelForGraph(g);
String qs = "PREFIX : <http://example/> " +
"SELECT (:stddev(?price) AS ?stddev) " +
"WHERE { ?item :hasPrice ?price }";
// Execute query and print results
Query q = QueryFactory.create(qs) ;
QueryExecution qexec = QueryExecutionFactory.create(q, m);
ResultSet rs = qexec.execSelect() ;
ResultSetFormatter.out(rs);
}
}
我希望这个例子至少对某人有所帮助,即使这个问题是几年前发布的。