保存并重用SPARQL查询的结果

时间:2013-07-20 20:46:19

标签: java eclipse sparql jena

我正在使用Jena通过Eclipse查询owl文件。我想做一些连续的查询,每个新查询都将使用前一个查询的结果。我想用不同的方法做什么?每次查询结果时选择并保存,以便在新查询中再次使用它。我不想自己插入变量的值,但自动从查询中发生。任何想法是否有适当的方法来实现这一目标?提前致谢

2 个答案:

答案 0 :(得分:3)

我认为这里有两个主要选项:

  1. 。如果您只对ResultSet中的一个QuerySolution感兴趣并且您在本地运行这些查询,则可以使用QuerySolution并将其用作QueryExecution的initialBindings参数,以及变量中的变量值。 QuerySolution将用于第二个查询。这可能仅适用于本地查询(因为ResultSet中的某些值可能是空值节点,其值在远程上下文中没有意义),并且仅在您有一个感兴趣的QuerySolution时才有用。
    1. B'/ em>的。单个QuerySolution还可用于在ParameterizedSparqlString中设置一些值。在这种情况下,在创建实际的Query或QueryExecution对象之前替换值,如果需要,还可以执行其他操作。如果某些结果是空白节点,您可能无法可靠地运行远程查询,但能够将此方法用于远程端点,而您无法使用{{1方法。

    2. 更通用的解决方案使用SPARQL 1.1's VALUES在VALUES块中提供ResultSet的内容。这样更容易移植,因为任何端点都应该能够处理VALUES块,而且它更通用,因为它可以处理一堆绑定,而不仅仅是一个绑定。

    3. initialBindings

      这是生成的输出。在第一种情况下,Alice的地址被选中的事实表明import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; import com.hp.hpl.jena.query.ParameterizedSparqlString; import com.hp.hpl.jena.query.QueryExecution; import com.hp.hpl.jena.query.QueryExecutionFactory; import com.hp.hpl.jena.query.QuerySolution; import com.hp.hpl.jena.query.QuerySolutionMap; import com.hp.hpl.jena.query.ResultSet; import com.hp.hpl.jena.query.ResultSetFormatter; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.sparql.core.Var; import com.hp.hpl.jena.sparql.engine.binding.Binding; public class ReuseResults { final static String turtleContent = "" + "@prefix : <http://example.org/> .\n" + "\n" + ":alice :hasName \"Alice\" .\n" + ":alice :hasAddress \"4222 Clinton Way\" .\n" + ":herman :hasName \"Herman\".\n" + ":herman :hasAddress \"1313 Mockingbird Lane\" .\n" + ":DrWho :hasAddress \"The TARDIS\"" + ""; // Read the model from the turtle content final static Model model = ModelFactory.createDefaultModel() .read( new ByteArrayInputStream( turtleContent.getBytes()), null, "TURTLE" ); final static String findAlice = "" + "prefix : <http://example.org/>\n" + "select ?alice where {\n" + " ?alice :hasName \"Alice\" .\n" + "}\n" + ""; final static String findAliceAddress = "" + "prefix : <http://example.org/>\n" + "select ?address where {\n" + " ?alice :hasAddress ?address .\n" + "}\n" + ""; public static void useInitialBindingsFromQuerySolution() throws IOException { System.out.println( "== useInitialBindingsFromQuerySolution ==" ); // execute the query that finds a binding for ?alice. There should be just one // query solution in the result set. final ResultSet aliceResults = QueryExecutionFactory.create( findAlice, model ).execSelect(); final QuerySolution solution = aliceResults.next(); // Use the single query solution from the result set as initial bindings for // the second query (which uses the variable ?alice). final ResultSet addressResults = QueryExecutionFactory.create( findAliceAddress, model, solution ).execSelect(); ResultSetFormatter.out( addressResults ); } public static void useParameterizedSPARQLString() { System.out.println( "== useParameterizedSPARQLString ==" ); // execute the query that finds a (single) binding for ?alice. Then create // a query solution map containing those results. final ResultSet aliceResults = QueryExecutionFactory.create( findAlice, model ).execSelect(); final QuerySolutionMap map = new QuerySolutionMap(); map.addAll( aliceResults.next() ); // Create a ParameterizedSparqlString from the findAliceAddress query string (if this // approach were taken, findAliceAddress could actually *be* a Param.SparqlString, of // course). final ParameterizedSparqlString pss = new ParameterizedSparqlString( findAliceAddress ); System.out.println( pss.toString() ); pss.setParams( map ); System.out.println( pss.toString() ); // execute the query and show the results ResultSetFormatter.out( QueryExecutionFactory.create( pss.toString(), model ).execSelect() ); } final static String findNamed = "" + "prefix : <http://example.org/>\n" + "select ?person where {\n" + " ?person :hasName [] .\n" + "}\n" + ""; final static String findPersonAddress = "" + "prefix : <http://example.org/>\n" + "select ?address where { " + " ?person :hasAddress ?address .\n" + "}\n" + ""; public static void useValuesFromResultSet() { System.out.println( "\n== useValuesFromResultSet ==" ); final ResultSet namedResults = QueryExecutionFactory.create( findNamed, model ).execSelect(); final QueryExecution qe = QueryExecutionFactory.create( findPersonAddress, model ); System.out.println( "=== Query Before Adding VALUES ===\n" + qe.getQuery() ); // Create a list of the variables from the result set List<Var> variables = new ArrayList<>(); for ( final String varName : namedResults.getResultVars() ) { variables.add( Var.alloc( varName )); } // Create a list of the bindings from the result set. List<Binding> values = new ArrayList<>(); while ( namedResults.hasNext() ) { values.add( namedResults.nextBinding() ); } // add a values block to the query qe.getQuery().setValuesDataBlock(variables, values); System.out.println( "\n=== Query After Adding VALUES ===\n" + qe.getQuery() ); ResultSetFormatter.out( qe.execSelect() ); } public static void main(String[] args) throws IOException { useInitialBindingsFromQuerySolution(); // 1.a. useParameterizedSPARQLString(); // 1.b. useValuesFromResultSet(); // 2. } } 的值从第一个ResultSet传递到?alice。在第二种情况下,我在添加VALUES子句之前和之后打印了查询,以便区分清楚。请注意,即使ResultSet绑定多个变量,这也会起作用。多个变量的语法是initialBindings

      VALUES (?v1 ... ?vN) { (value11 ... value1N) ... (valueM1 ... valueMN) }

答案 1 :(得分:-1)

  1. 据我所知,SPARQL中有级联查询,如SQL。
  2. 将结果存储在文件中,并在sparql查询中匹配。
  3. 可能适合你。

    参阅: http://www.w3.org/TR/sparql11-query/