跳转到内容

SPARQL/基础

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

SPARQL 看起来可能很复杂,但简单基础已经可以让你走很远 - 如果你愿意,你可以在本章之后停止阅读,你已经知道足够编写许多有趣的查询。其他章节只是添加了更多主题的信息,你可以用它们来编写不同的查询。它们中的每一个都将使你能够编写更棒的查询,但它们都不是必需的 - 你可以随时停止阅读,并希望仍然能获得大量有用的知识!

此外,如果你以前从未听说过维基数据、SPARQL 或 WDQS,这里简要解释一下这些术语。

SPARQL 基础

[编辑 | 编辑源代码]

一个简单的 SPARQL 查询如下所示

SELECT ?a ?b ?c
WHERE
{
  x y ?a.
  m n ?b.
  ?b f ?c.
}

SELECT 子句列出了你想要返回的变量(变量以问号开头),而 WHERE 子句包含对它们的限制,主要是三元组的形式。维基数据(以及类似的知识数据库)中的所有信息都以三元组的形式存储;当你运行查询时,查询服务会尝试用实际值填充变量,以便生成的元组出现在知识数据库中,并为它找到的每个变量组合返回一个结果。

三元组可以像句子一样阅读(这就是它以句号结尾的原因),包含一个主语、一个谓语和一个宾语

SELECT ?fruit
WHERE
{
  ?fruit hasColor yellow.
  ?fruit tastes sour.
}

此查询的结果可能包括,例如,“柠檬”。在维基数据中,大多数属性是“有”-类型的属性,因此查询可以改写为

SELECT ?fruit
WHERE
{
  ?fruit color yellow.
  ?fruit taste sour.
}

读起来就像“?fruit 颜色‘黄色’”(不是?fruit ‘黄色’的颜色” - 请记住这对“父母”/“孩子”之类的属性!)。

但是,这不是 WDQS 的好例子。味道是主观的,所以维基数据没有关于它的属性。相反,让我们考虑一下父母/孩子关系,它们大多是明确的。

我们的第一个查询

[编辑 | 编辑源代码]

假设我们想要列出巴洛克作曲家约翰·塞巴斯蒂安·巴赫的所有孩子。使用上面的查询中的伪元素,你将如何编写该查询?

希望你得到类似这样的东西

SELECT ?child
WHERE
{
  # either this...
  ?child parent Bach.
  # or this...
  ?child father Bach.
  # or this.
  Bach child ?child.
  # (note: everything after a ‘#’ is a comment and ignored by WDQS.)
}

前两个三元组表示 ?child 必须有父母/父亲巴赫;第三个表示巴赫必须有孩子 ?child。让我们暂时使用第二个。

那么要把它变成一个真正的 WDQS 查询,还需要做什么呢?在维基数据中,项目和属性不是由人类可读的名称来标识的,比如“父亲”(属性)或“巴赫”(项目)。(有充分的理由:“约翰·塞巴斯蒂安·巴赫”也是一位 德国画家 的名字,而“巴赫”也可能指 姓氏法国公社水星陨石坑 等等)。相反,维基数据项目和属性被分配了一个标识符。要查找项目的标识符,我们 搜索 项目并复制看起来像是我们正在寻找的项目的 Q 号码(例如,基于描述)。要查找属性的标识符,我们执行相同的操作,但搜索“P:搜索词”而不是仅仅是“搜索词”,这将搜索限制为属性。这告诉我们,著名的作曲家约翰·塞巴斯蒂安·巴赫是 Q1339,而指定项目父亲的属性是 P22

最后但同样重要的是,我们需要包含前缀。对于简单的 WDQS 三元组,项目应该以 wd: 为前缀,属性应该以 wdt: 为前缀。(但这仅适用于固定值 - 变量没有前缀!)。

将这些放在一起,我们得到了第一个真正的 WDQS 查询

SELECT ?child
WHERE
{
# ?child  father   Bach
  ?child wdt:P22 wd:Q1339.
}

试试吧!

点击“试试吧”链接,然后在 WDQS 页面上“运行”查询。你得到了什么?

child
wd:Q57225
wd:Q76428

好吧,这令人失望。你只看到标识符。你可以点击它们查看它们的维基数据页面(包括人类可读的标签),但有没有更好的方法来查看结果呢?

好吧,事实证明,有! (反问句真是太好了!)。如果你在 WHERE 子句中包含魔法文本

SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }

你会得到额外的变量:对于查询中的每个变量 ?foo,你现在还有一个变量 ?fooLabel,它包含 ?foo 背后的项目的标签。如果你将它添加到 SELECT 子句中,你将得到项目及其标签

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

试试吧!

尝试运行该查询 - 你应该不仅看到项目编号,而且还看到各种孩子的姓名。

child childLabel
wd:Q57225 约翰·克里斯托弗·弗里德里希·巴赫
wd:Q76428 卡尔·菲利普·埃曼努埃尔·巴赫

这完成了基础知识。尝试通过改变属性来修改它。

参考文献

[编辑 | 编辑源代码]


华夏公益教科书