SPARQL/三元组
语句“天空是蓝色的”包含主体(“天空”)、谓词(“是”)和宾语(“蓝色”)。
SPO 或“主体、谓词、宾语”被称为(语义)三元组,在维基数据中通常被称为关于数据的陈述。
SPO 也用作查询 RDF 数据结构或任何图数据库或三元组存储(如维基数据查询服务 (WDQS))的基本语法布局形式。
另见 w:en:语义三元组
在维基数据查询服务 (WDQS) 中,三元组用于描述查询模式在SELECT
语句的WHERE
子句中。
# ?child father Bach ?child wdt:P22 wd:Q1339.
在这种情况下,三元组?child wdt:p22 wd:Q1339
指定变量?child
必须具有父/父亲巴赫。
三元组的任何部分主体、谓词和宾语都可能是变量。这使得这种选择非常灵活。
可以通过添加额外的三元组来添加额外的变量。在最简单的情况下,这些三元组使用相同的主体。
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 BY
、GROUP_CONCAT
、DISTINCT
,并且所有标签都应在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:dateModified
、wikibase:statements
和wikibase: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". }
}