SPARQL functions in CONSTRUCT/WHERE

2019-01-09 18:11发布

问题:

I mostly use SPARQL SELECT while working on a query for debugging purposes but in the end I want to use the final result it in a CONSTRUCT way; as I want to work with a graph and not key/value query results.

What I don't get yet (and can't seem to find with search engines/docs) is if I can use functions as well that way. As an example, I use a property path to concatenate titles I get into a "superstring", which I later use for building a Lucene index to increase plain text search quality:

PREFIX dc: <http://purl.org/dc/elements/1.1/>    

SELECT (group_concat(?title ; separator = " ") AS ?fancytitle) WHERE { 
  GRAPH ?graph {
    <http://data.staatsarchiv-bs.ch/id/archivalresource/CH-000027-1/pa-633c-a-312-fasc-163>  dc:relation+ ?relation .
    ?relation dc:title ?title .
  }
}

Now I would like to have the same ?fancytitleas a new triple like

<http://data.staatsarchiv-bs.ch/id/archivalresource/CH-000027-1/pa-633c-a-312-fasc-163> <fancytitle> ?fancytitle .

So I can store it directly in a new graph. Is this possible? I played with some queries but couldn't manage to get it accepted by the SPARQL processor. FYI I'm using Fuseki.

You can try it out at my SPARQL Endpoint

回答1:

Yes this is possible

You can't use expressions directly in a CONSTRUCT template but you can assign the variable in the WHERE clause either via a SELECT expression in a sub-query or using BIND.

In your case as GROUP_CONCAT is an aggregate it can only be a SELECT expression so you just need to put your entire SELECT as a sub-query e.g.

PREFIX dc: <http://purl.org/dc/elements/1.1/>    

CONSTRUCT
{
  <http://data.staatsarchiv-bs.ch/id/archivalresource/CH-000027-1/pa-633c-a-312-fasc-163> <http://fancyTitle> ?fancytitle
}
WHERE
{
  SELECT (group_concat(?title ; separator = " ") AS ?fancytitle) WHERE { 
    GRAPH ?graph {
      <http://data.staatsarchiv-bs.ch/id/archivalresource/CH-000027-1/pa-633c-a-312-fasc-163>  dc:relation+ ?relation .
      ?relation dc:title ?title .
    }
  }
}

The above works fine on your endpoint



回答2:

With the help of my colleague we got it to work, UNION and GROUP BY are essential. This query puts the string together for all locah:ArchivalResource in the graphs:

CONSTRUCT
{
  ?archresource skos:hiddenLabel ?supertitle
}
WHERE
{
  SELECT ?archresource  (group_concat(?title ; separator = ", ") AS ?supertitle) WHERE {
    GRAPH ?graph {
      {
        SELECT ?title ?archresource WHERE {
          GRAPH ?graph {
            {
              ?archresource a locah:ArchivalResource ;
              dc:title ?title .
            } UNION
            {
              ?archresource dc:relation+ ?relation .
              ?relation dc:title ?title .
            }
          }
        }
      }
    }
  } GROUP BY ?archresource
}