SPARQL: вставить результаты запроса в виде RDF LIST - PullRequest
0 голосов
/ 05 июля 2018
  1. Я хочу получить из графика Результаты, привязанные к определенной переменной, скажем? 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 голосов
/ 06 июля 2018

Я не думаю, что это возможно, используя только 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);
...