为什么SPARQL查询下面不返回笛卡尔积(why sparql query below do not

2019-10-19 08:31发布

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

我运行它免受加滕伯格项目数据。 数据的形式为:

 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

所以没有笛卡尔乘积像SQL。

那是在炫技或功能中的错误?

请注意, ?p的片段?ID1 ?p ?autor1. 有没有因为数据内没有“作者的真名”属性。 加滕伯格只给出了这样的字符串: 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 author2)为“谜”一书。

Answer 1:

文字不能科目:

你不向我们展示的数据或结果完全吻合。 如果数据是实际的形式:

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

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

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

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

将查询重写

我下载了RDF-files.tar.bz2从当前RDF格式的部分可从Project Gutenberg的RDF数据 。 并指出,经过奥秘有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 .

最后结果

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

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


文章来源: why sparql query below do not return cartesian product