SPARQL:将查询结果作为RDF LIST插入

时间:2018-07-05 13:36:34

标签: sparql rdf rdfs blazegraph rdf4j

  1. 我想从图A中获得一个绑定到特定变量的结果,可以说?s。

  2. 下一步,我要将这些结果作为RDF列表插入到图B中。

这是我的SPARQL更新:

prefix foo:<http://foo.com/>
insert
{
    graph <http://B.com>
    {
        ?var foo:propA foo:A ;
             foo:propB [ foo:propA foo:A ;
                         foo:propX ( ?s )
                        ] ;
             foo:propC ?o .
    }
}
where
{
    graph <http://A.com>
    {
        ?s ?p ?o.
        BIND(URI(CONCAT("http://example.org/", STRAFTER( STR(?o), "http://someuri.org/"))) as ?var)
    }
}

我的问题是它插入了以下数据:

<http://example.org/varX> foo:propA foo:A ;
                          foo:propB [ foo:propA foo:A ;
                                      foo:propX ( <http://s1.com> )
                                    ],
                                    [
                                      foo:propA foo:A ;
                                      foo:propX ( <http://s2.com> )
                                    ] ;
                          foo:propC <http://oX.com> .

相反,我希望它插入它:

<http://example.org/varX> foo:propA foo:A ;
                          foo:propB [ foo:propA foo:A ;
                                      foo:propX ( <http://s1.com> <http://s2.com> )
                                    ] ;
                          foo:propC <http://oX.com> .

我可以达到这个结果吗?

基本上我想为foo:propX谓词设置对象,RDF列表包含绑定到变量?s的元素值。

注意:完全相同的查询在RDF4J中可以很好地执行,但是奇怪的是导致Blazegraph抛出了一个错误

MalformedQueryException: Undefined vocabulary: http://www.w3.org/1999/02/22-rdf-syntax-ns#first

1 个答案:

答案 0 :(得分:1)

我认为仅使用SPARQL是不可能的。您需要使用一些API功能来创建RDF集合。

执行此操作的一种方法是,首先将graphB构造为内存中的Model对象,然后最后一次插入该模型。遵循这些原则(未经测试,但这应该可以说明一般思想-有关更多详细信息,请参阅RDF4J文档和javadoc):

   ValueFactory vf = conn.getValueFactory();

   TupleQuery query = conn.prepareTupleQuery("SELECT ?s ?o ?var WHERE ...");
   List<BindingSet> queryResult = QueryResults.asList(query.evaluate());

   // map values of var to values of S
   Map<Value, List<Value>> varToS = new HashMap<>();
   ... // do something clever with the query result to fill this HashMap 

   // start building our result graph
   Model graphB = new TreeModel()
   ModelBuilder mb = new ModelBuilder(graphB);
   mb.setNamespace("foo", "http://example.org/");
   mb.namedGraph("foo:graphB");

   for(Value var: varToS.keySet()) {
      BNode propBValue = vf.createBNode();
      BNode propXValue = vf.createBNode();

      mb.subject(var)
           .add("foo:propA", "foo:A")
           .add("foo:propB", propBValue)
        .subject(propBValue)
           .add("foo:propA", "foo:A")
           .add("foo:propX", propXValue);
      // add the values of ?s for the given v as a collection
      RDFCollections.asRDF(varToSet.get(var), propXValue, graphB);                
   }

   // insert our created graphB model into the database
   conn.add(graphB);