2015-12-05 105 views
1

我模仿专辑中的歌曲如下:如何在4store中重用SPARQL子查询的结果?

@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 . 

我希望能够访问一张专辑的最后一首歌曲的名字。

所以我想到了第一次通过计算有多少歌曲专辑,让最后一首歌的md:position包含

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

产生正确的结果“3”:

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

后来想通过使用上面的查询作为子查询重用此结果。我怎样才能做到这一点?我试过如下:

SELECT ?songName WHERE { 

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

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

} 

然而,这并不工作,并产生所有三首歌曲:

<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> 

为什么会出现这种情况,什么是这样做的正确方法是什么?我正在使用三重商店4store

回答

1

它看起来像它在4store的错误。你可能应该向他们报告。你用Jena得到的结果是你所期望的:

<?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> 

但是,你不需要子查询来做到这一点。你可以把这首歌的位置放在没有更大位置的歌曲上:

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

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

谢谢你的替代解决方案。只要我有足够的声誉,就会立刻起效。不幸的是,4store似乎并不支持这一点:_parser错误:语法错误,意外的不在第9_行。或者我做错了什么。我会尽力与他们取得关于这两种情况的联系。 – nistel

+0

@nistel 2013年,它看起来像“过滤器不存在”尚未支持([Google网上论坛帖子]](https://groups.google.com/forum/#!topic/4store-support/k0ny4w8nZ9w))。解决方法是使用“减号”。不过,我不知道这是否会起作用。 –

+0

谢谢Joshua指出这一点。该查询将执行,但不会返回对songName的绑定。我在那边打开了一个线程(尚未批准)。 – nistel