我想从图A中获得一个绑定到特定变量的结果,可以说?s。
下一步,我要将这些结果作为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
答案 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);