跳转到内容

SPARQL/三元组

来自维基教科书,开放世界开放书籍

语句“天空是蓝色的”包含主体(“天空”)、谓词(“是”)和宾语(“蓝色”)。

SPO 或“主体、谓词、宾语”被称为(语义)三元组,在维基数据中通常被称为关于数据的陈述。

SPO 也用作查询 RDF 数据结构或任何图数据库或三元组存储(如维基数据查询服务 (WDQS))的基本语法布局形式。

另见 w:en:语义三元组

在维基数据查询服务 (WDQS) 中,三元组用于描述查询模式SELECT 语句WHERE 子句中。

# ?child  father   Bach
  ?child wdt:P22 wd:Q1339.

在这种情况下,三元组?child wdt:p22 wd:Q1339 指定变量?child 必须具有父/父亲巴赫。

三元组的任何部分主体、谓词和宾语都可能是变量。这使得这种选择非常灵活。

具有相同主体的三元组

[编辑 | 编辑源代码]
Example of SPARQL Triples
SPARQL 三元组示例

可以通过添加额外的三元组来添加额外的变量。在最简单的情况下,这些三元组使用相同的主体。

SELECT ?child ?childLabel ?genderLabel ?birth_date ?date_of_death
WHERE
{
  ?child wdt:P22 wd:Q1339.# ?child  has father   Bach
  ?child wdt:P21 ?gender.
  ?child wdt:P569 ?birth_date.
  ?child wdt:P570 ?date_of_death.
  SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}

试试吧!

第一个三元组选择巴赫的所有孩子。额外的三元组将所有这些三元组与性别、出生日期和死亡日期的值链接在一起。变量?child 将它们全部链接在一起。

如果你仔细观察结果,你可能会注意到约翰·克里斯托夫·弗里德里希·巴赫在列表中有 2 行,因为有 2 个不同的出生日期,6 月 21 日和 23 日 1732 年。在他的情况下,?child wdt:P569 ?birth_date. 产生了 2 个值。有关更多详细信息,请参阅删除重复项修饰符

可选三元组

[编辑 | 编辑源代码]

如果并非所有主体都对某个三元组有值,则该主体将被排除。为了将其包括在内,OPTIONAL 关键字非常有用。

SELECT DISTINCT ?child ?childLabel ?genderLabel ?birth_date ?date_of_death
WHERE
{
  ?child wdt:P22 wd:Q76.# ?child  has father   Obama
  OPTIONAL{ ?child wdt:P21 ?gender. }
  OPTIONAL{ ?child wdt:P569 ?birth_date. }
  OPTIONAL{ ?child wdt:P570 ?date_of_death. }
  SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}

试试吧!

两个孩子都显示出来,即使其中一个变量(在本例中是死亡日期)没有填写。

有关完整说明,请参阅可选章节。

复杂三元组

[编辑 | 编辑源代码]

三元组不限于一个主体。事实上,三元组可以以任何可想象的方式链接。

例如,你可以列出巴赫子女出生地点的坐标。

SELECT ?child ?childLabel ?placeofbirthLabel ?coordinates
WHERE
{
  ?child wdt:P22 wd:Q1339.# ?child  has father   Bach
  ?child wdt:P19 ?placeofbirth.
  ?placeofbirth wdt:P625 ?coordinates. 
  SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
ORDER BY ?placeofbirthLabel

试试吧!

你甚至可以通过使用#defaultView:Map 在地图上看到这些出生地点(科腾、莱比锡和魏玛)。

#defaultView:Map
SELECT ?placeofbirthLabel ?coordinates
       (GROUP_CONCAT(DISTINCT ?childLabel; SEPARATOR=", ") AS ?children)
WHERE
{
  ?child wdt:P22 wd:Q1339.# ?child  has father   Bach
  ?child wdt:P19 ?placeofbirth.
  ?placeofbirth wdt:P625 ?coordinates. 
  SERVICE wikibase:label { bd:serviceParam wikibase:language "en". 
                         ?child        rdfs:label ?childLabel.
                         ?placeofbirth rdfs:label ?placeofbirthLabel.
                         }
}
GROUP BY ?placeofbirthLabel ?coordinates ?children

试试吧!

如果你点击一个红点,你将获得如上所述的附加数据,使用变量?placeofbirthLabel?children。我们必须使用GROUP BYGROUP_CONCATDISTINCT,并且所有标签都应在SERVICE 中明确定义。你可以通过“显示”下拉列表(位于“运行”按钮的右侧)在“地图”显示和标准表格显示之间切换。

有关视图的更多信息,请参阅地图视图所有视图

按变量数量分类的三元组

[编辑 | 编辑源代码]

只有一个变量的三元组

[编辑 | 编辑源代码]

一个示例,使用主体作为变量的三元组:

SELECT ?child ?childLabel
WHERE
{
  ?child wdt:P22 wd:Q1339.         # ?child  has father   Bach
  SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}

试试吧!

这将列出所有主体(作为变量?child),具有谓词父亲 (P22) 和宾语约翰·塞巴斯蒂安·巴赫 (Q1339)

一个示例,使用谓词作为变量的三元组:

SELECT ?predicate ?pLabel
WHERE
{
  wd:Q57225 ?predicate wd:Q1339.         # Johann Christoph Friedrich Bach ?predicate Johann Sebastian Bach

  BIND( IRI(REPLACE( STR(?predicate),"prop/direct/","entity/" )) AS ?p). 
  # or ?p wikibase:directClaim ?predicate. 
  SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}

试试吧!

这将列出所有谓词(作为变量?predicate),具有宾语约翰·克里斯托夫·弗里德里希·巴赫 (Q57225) 和主体约翰·塞巴斯蒂安·巴赫 (Q1339)
它表明他不仅是他的父亲 (P22),而且也是他的学生 (P1066)

一个示例,使用宾语作为变量的三元组:

SELECT ?workloc ?worklocLabel
WHERE
{
  wd:Q1339 wdt:P937 ?workloc.         # Bach  work location  ?workloc
  SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}

试试吧!

这将列出所有宾语(作为变量?workloc),具有主体约翰·塞巴斯蒂安·巴赫 (Q1339) 和谓词工作地点 (P937)

有两个变量的三元组

[编辑 | 编辑源代码]

一个示例,使用 2 个变量,并且主体只有一个固定值,将列出关于巴赫的所有原始信息,在维基数据中可用。

SELECT ?predicate ?object
WHERE
{
  wd:Q1339 ?predicate ?object.         # Bach
}

试试吧!

有关更多用法,请参阅下一节中包含 3 个变量的三元组。

一个示例,使用 2 个变量,并且谓词只有一个固定值,将列出所有具有 IATA 机场代码的主体(可能是机场)。

SELECT ?subject ?subjectLabel ?object
WHERE
{
  ?subject wdt:P238 ?object.         # IATA airport code
  SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
ORDER BY ?object

试试吧!

一个用法可以是检查重复的 IATA 代码。

SELECT ?object (COUNT(?subject) AS ?count)
               (MIN(?subject) AS ?subject1) (MAX(?subject) AS ?subject2)
               (GROUP_CONCAT(DISTINCT ?subjectLabel; SEPARATOR=", ") AS ?subjectLabels)
WHERE
{
  ?subject wdt:P238 ?object.         # IATA airport code
  SERVICE wikibase:label { bd:serviceParam wikibase:language "en". 
                         ?subject rdfs:label ?subjectLabel.
                         }
}
GROUP BY ?object
HAVING(COUNT(?subject) > 1)
ORDER BY ?object

试试吧!

一个示例,使用 2 个变量,并且宾语只有一个固定值,将列出所有与巴赫相关的主体。

SELECT ?subject ?subjectLabel ?subjectDescription ?predicate ?pLabel
WHERE
{
  ?subject ?predicate wd:Q1339.  # Bach

  BIND( IRI(REPLACE( STR(?predicate),"prop/direct/","entity/" )) AS ?p). 
  # or ?p wikibase:directClaim ?predicate. 
  SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
ORDER BY ?subject

试试吧!

使用宾语作为固定值的另一个可能性将列出所有具有值“ABC”的主体,并将显示例如阿尔瓦塞特机场。

SELECT ?subject ?subjectLabel ?subjectDescription ?predicate ?pLabel
WHERE
{
  ?subject ?predicate "ABC". 

  BIND( IRI(REPLACE( STR(?predicate),"prop/direct/","entity/" )) AS ?p). 
  # or ?p wikibase:directClaim ?predicate. 
  SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
ORDER BY ?subject

试试吧!

有三个变量的三元组

[编辑 | 编辑源代码]

当你使用所有 3 个变量作为变量(一个用于主体,一个用于谓词,一个用于宾语)的三元组时,你实际上将列出整个数据库。这对于小型数据库可以做到,也可以用于大致了解所有可用属性上的可用数据。

关于巴赫子女的所有原始信息,在维基数据中可用。

SELECT ?subject ?predicate ?object 
WHERE
{
  ?subject ?predicate ?object.
  ?subject wdt:P22 wd:Q1339.		# subject has father   Bach
}
ORDER BY ?subject ?predicate ?object
LIMIT 10000

试试吧!

相同的查询,但按谓词分组。

SELECT DISTINCT ?subject ?subjectLabel ?predicate 
       (GROUP_CONCAT(DISTINCT ?object; SEPARATOR=", ") AS ?objects)
WHERE
{
  ?subject ?predicate ?object.
  ?subject wdt:P22 wd:Q1339.		# subject has father   Bach
  SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
GROUP BY ?subject ?subjectLabel ?predicate
ORDER BY ?subject ?subjectLabel ?predicate
LIMIT 10000

试试吧!

从下面的查询中,你可以发现有关维基数据页面上次更新日期、语句总数、站点链接数量等的元组。这些分别是schema:dateModifiedwikibase:statementswikibase:sitelinks

SELECT ?subject ?subjectLabel ?datemodified ?statements ?sitelinks 
WHERE
{
  ?subject wdt:P22 wd:Q1339.		# subject has father   Bach
  ?subject schema:dateModified ?datemodified.
  ?subject wikibase:statements ?statements.
  ?subject wikibase:sitelinks  ?sitelinks.
  SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}

试试吧!


华夏公益教科书