2014-02-16 135 views
1

我是sparql领域的初学者。我已经写了这个查询:为什么下面的sparql查询不返回笛卡尔积

prefix pp: <http://purl.org/dc/elements/1.1/> 
select ?title,?autor1, ?autor2 
from <http://gutenberg.lib> 
where { 
     ?s pp:title ?title. 
     ?s pp:creator ?ID1. 
     ?ID1 ?p ?autor1. 
     optional{ ?s pp:creator ?ID2. 
       ?ID2 ?p ?autor2. 
       } 
} order by ?s 

我运行它对guttenberg项目的数据。数据的形式为:

S1 pp:title "TITLE11" 
S1 pp:creator "CREATOR11" 
S1 pp:creator "CREATOR12" 
S2 pp:title "TITLE21" 
S2 pp:creator "CREATOR21" 
S2 pp:creator "CREATOR22" 
S2 pp:creator "CREATOR23" 

我希望我得到类似的东西:

TITLE11, CREATOR11, CREATOR11 
TITLE11, CREATOR11, CREATOR12 
TITLE11, CREATOR12, CREATOR11 
TITLE11, CREATOR12, CREATOR12 

,但我得到类似的东西:

TITLE11, CREATOR11, CREATOR11 
TITLE11, CREATOR12, CREATOR12 

所以没有笛卡尔产品 like for SQL。

这是Virtuoso或功能中的错误吗?

请注意,片段?ID1 ?p ?autor1.中的?p存在,因为数据中没有“作者实名”属性。加滕伯格只给出了这样的字符串:http://www.w3.org/1999/02/22-rdf-syntax-ns#_1 1-ST作者,http://www.w3.org/1999/02/22-rdf-syntax-ns#_2为第二等


例如(真实数据),它看起来像这样:

The Mystery  http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag 

The Mystery  White, Stewart Edward, 1873-1946 White, Stewart Edward, 1873-1946 

The Mystery  Adams, Samuel Hopkins, 1871-1958 Adams, Samuel Hopkins, 1871-1958 

,并没有其他的三部曲(标题,作者1作者2)为“神秘”一书。

+0

问题复制在http://answers.semanticweb.com/questions/26498/why-sparql- does-not-give-cartesian-product –

回答

8

字面不能科目:

你不向我们展示了数据或精确的结果。如果数据实际上是形式:

S1 pp:title "TITLE11" 
S1 pp:creator "CREATOR11" 
S1 pp:creator "CREATOR12" 

其中creator属性的值是字符串,那么你不应该得到任何比赛

?s pp:creator ?ID1. 
?ID1 ?p ?autor1. 

因为?ID1将被绑定到一个字符串,然后你不能有任何匹配的第二行,因为字符串不能是RDF三元组的主题。

将查询重写

我从RDF data available from Project GutenbergCurrent RDF Format部分下载的rdf-files.tar.bz2。并指出The Mystery有10008后,我浏览到该文件cache/epub/10008/pg10008.rdf,我看到这个数据(以下简称为相关部分):

<http://www.gutenberg.org/ebooks/10008> 
     dcterms:creator <http://www.gutenberg.org/2009/agents/1635> , <http://www.gutenberg.org/2009/agents/247> ; 
     dcterms:title  "The Mystery" . 

<http://www.gutenberg.org/2009/agents/1635> 
     pgterms:alias  "Fabian, Warner" ; 
     pgterms:name  "Adams, Samuel Hopkins" . 

<http://www.gutenberg.org/2009/agents/247> 
     pgterms:name  "White, Stewart Edward" . 

值得注意的是,我没有看到该文件的任何使用rdf:Bag。也许你正在使用传统的RDF格式,也可以下载。如果您决定使用它,请添加评论,我们也可以开展这项工作,但在可用的情况下使用新数据似乎是有益的,因此我会继续使用这些数据。

如果您希望每个标题都与作者的每个组合一起列出,则可以使用类似下面的查询来获得结果。 (我注意到你说你期望重复的作者,这对我来说似乎有点不同寻常,所以我添加了一个过滤器来删除这些过滤器,但是如果你真的希望?name_i?name_j能够绑定到相同的值。)

prefix dcterms: <http://purl.org/dc/terms/> 
prefix pgterms: <http://www.gutenberg.org/2009/pgterms/> 

select ?title ?name_i ?name_j where { 
    ?work dcterms:title ?title ; 
     dcterms:creator ?creator_i . 
    ?creator_i pgterms:name ?name_i . 
    optional { 
    ?work dcterms:creator ?creator_j . 
    ?creator_j pgterms:name ?name_j . 
    filter(?creator_i != ?creator_j) 
    } 
} 
--------------------------------------------------------------------- 
| title   | name_i     | name_j     | 
===================================================================== 
| "The Mystery" | "Adams, Samuel Hopkins" | "White, Stewart Edward" | 
| "The Mystery" | "White, Stewart Edward" | "Adams, Samuel Hopkins" | 
--------------------------------------------------------------------- 

清理查询

上面的查询就足以让你去,但实际上你可以让它多一点简洁。

空节点

既然你不凸出的?creator_i?creator_j的价值,实际上你可以使用空白节点位置;而不是写:

?work dcterms:title ?title ; 
     dcterms:creator ?creator_i . 
?creator pgterms:name ?name_i . 

你可以写

?work dcterms:title ?title ; 
     dcterms:creator [ pgterms:name ?name_i ] . 

房产路径

而且因为你只关心创作者一个属性,可以让这个更短带属性路径:

?work dcterms:title ?title ; 
     dcterms:creator/pgterms:name ?name_i . 

Final Resu LT

这样做之后,你有这样的查询和结果:

prefix dcterms: <http://purl.org/dc/terms/> 
prefix pgterms: <http://www.gutenberg.org/2009/pgterms/> 

select ?title ?name_i ?name_j where { 
    ?work dcterms:title ?title ; 
     dcterms:creator/pgterms:name ?name_i . 
    optional { 
    ?work dcterms:creator/pgterms:name ?name_j . 
    filter(?name_i != ?name_j) 
    } 
} 
--------------------------------------------------------------------- 
| title   | name_i     | name_j     | 
===================================================================== 
| "The Mystery" | "Adams, Samuel Hopkins" | "White, Stewart Edward" | 
| "The Mystery" | "White, Stewart Edward" | "Adams, Samuel Hopkins" | 
--------------------------------------------------------------------- 
+0

是的,它看起来像我使用旧的数据格式。我会尝试更新的,我会看到它会得到什么... – kakaz