nistel
nistel

Reputation: 123

How to reuse the result of a SPARQL subquery in 4store?

I modelled the songs of an album as follows:

@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

@prefix md: <http://example.com/music-discography#> .

md:album1 md:songs-of-album md:song1 .
md:album1 md:songs-of-album md:song2 .
md:album1 md:songs-of-album md:song3 .

md:song1 md:name "Song 1" .
md:song2 md:name "Song 2" .
md:song3 md:name "Song 3" .

md:song1 md:position "1"^^xsd:integer .
md:song2 md:position "2"^^xsd:integer .
md:song3 md:position "3"^^xsd:integer .

I would like to be able to access the name of the last song of an album.

Therefore I thought about first getting the md:position of the last song by calculating how many songs an album contains

SELECT (COUNT(*) AS ?lastposition)
WHERE {
  { md:album1 md:songs-of-album ?songInnerQuery }
}

which produces the correct result "3":

  <results>
    <result>
      <binding name="lastposition">
    <literal datatype="http://www.w3.org/2001/XMLSchema#integer">3</literal>
    </binding>
    </result>
  </results>

I then wanted to reuse this result by using the query above as a subquery. How can I do this? I tried the following:

SELECT ?songName WHERE {

  ?song md:position ?lastposition .
  ?song md:name ?songName

  { SELECT (COUNT(*) AS ?lastposition)
    WHERE {
      { md:album1 md:songs-of-album ?songInnerQuery }
    }
  }

}

However, this does not work and yields all three songs:

  <results>
    <result>
      <binding name="songName"><literal>Song 3</literal></binding>
    </result>
    <result>
      <binding name="songName"><literal>Song 2</literal></binding>
    </result>
    <result>
      <binding name="songName"><literal>Song 1</literal></binding>
    </result>
  </results>

Why does this happen and what is the correct way of doing this? I am using the triplestore 4store.

Upvotes: 1

Views: 178

Answers (1)

Joshua Taylor
Joshua Taylor

Reputation: 85853

It looks like it's a bug in 4store. You should probably report it to them. The results you get with Jena are what you'd expect:

<?xml version="1.0"?>
<sparql xmlns="http://www.w3.org/2005/sparql-results#">
  <head>
    <variable name="songName"/>
  </head>
  <results>
    <result>
      <binding name="songName">
        <literal>Song 3</literal>
      </binding>
    </result>
  </results>
</sparql>

But, you don't need a subquery to do this. You could take the song that has a position such that there are no songs with greater position:

SELECT ?songName WHERE {
  ?song md:position ?lastposition .
  ?song md:name ?songName

  filter not exists {
    ?song_ md:position ?position
    filter (?position > ?lastposition)
  }
}

Upvotes: 1

Related Questions