目录

  • 本篇内容
  • 一、SPARQL简述
  • 二、书中的例子
  • 2.1 匹配模式
  • 2.2 过滤器
  • 2.3 schema不同时的查询处理
  • 2.4 结果组织
  • 2.5 其他形式的SPARQL查询
  • 2.6 通过SPARQL更新来增加信息
  • 三、知乎上的例子
  • 参考文献


本篇内容

本篇主要介绍查询语义网所使用的SPARQL,以及转载知乎上实现的一个例子

一、SPARQL简述

当信息被表示为 RDF 后, 出于推理和应用开发的需要,我们需要能够存取其中相关的部分。在本章中, 我们将把注意力集中于一个叫做 SPARQL 的査询语言,它能够让我们通过选择、抽取等方式很容易地从被表示为RDF 的知识中获得特定的部分。 SPARQL 是专为 RDF 设计的,适合并依赖于万维网上的各种技术。

二、书中的例子

2.1 匹配模式

描述Baron Way公寓及其位置的rdf数据:

@prefix swp: <http://www.semanticwebprimer.org/ontology/apartments.ttl#>.
@prefix dbpedia: <http://dbpedia.org/resource/>.
@prefix dbpedia-owl: <http://dbpedia.org/ontology/>.
swp:BaronWayApartment swp:hasNumberOfBedrooms 3;
					  swp:isPart0f swp:BaronWayBuilding.
swp:BaronWayBuilding dbpedia-owl:location dbpedia:Amsterdam,
					 					  dbpedia:Netherlands.

假设我们想匹配建筑位置,即如下语句:

swp:BaronWayBuilding dbpedia-owl:location dbpedia:Amsterdam.

在 SPARQL 中,我们可以将三元组中的任何一个元素替换为一个变量。变量的首字符是
一个?(问号),要引人一个变量表示位置,我们可以这样写:

swp:BaronWayBuilding dbpedia-owl:location ?location.

完整SPARQL查询如下:

PREFIX swp: <http://www.semanticwebprimer.org/ontology/apartments.ttl#>.
PREFIX dbpedia: <http://dbpedia.org/resource/>.
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>.
SELECT ?location
WHERE {
	swp:BaronWayBuilding dbpedia-owl:location ?location.
}

查询的结果如下:

?location

http://dbpedia.org/resource/Amsterdam.

http://dbpedia.org/resource/Netherlands

我们并不局限于只匹配一个变量。我们可能想要找到三元组存储库中关于 Baron Way Apartment 的所有信息。 可以使用这条 SPARQL 査询:

PREFIX swp: <http://www.semanticwebprimer.0rg/ontology/apartments.ttl#>
PREFIX dbpedia: <http://dbpedia.org/resource/>.
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>.
SELECT ?p ?o
WHERE {
swprBaronWayApartment ?p ?o.
}

结果如下:

?p

?o

swp:hasNumberOfBedrooms

3

swp:isPartOf

swp:BaronWayBuilding

如果要对返回结果的条数进行限制,可加上LIMIT关键词

PREFIX swp: <http://www.semanticwebprimer.0rg/ontology/apartments.ttl#>
PREFIX dbpedia: <http://dbpedia.org/resource/>.
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>.
SELECT ?p ?o
WHERE {
swprBaronWayApartment ?p ?o.
}
LIMIT 10

2.2 过滤器

如果我们想要找的是拥有大于或小于一个特定数量的卧室的那些公寓。我们可以使用 SPARQL 来问这个问题,并使用 FILTER 关键词:

PREFIX swp: <http://www.semanticwebprimer.org/ontology/apartments.ttl#>.
PREFIX dbpedia: <http://dbpedia.org/resource/>.
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>.
SELECT ?apartment
WHERE {
?apartment swp:hasNumberOfBedrooms ?bedrooms.
FILTER (?bedrooms > 2).
}

结果是:

?apartment

swp:BaronWayApartment

如果我们的数据集包含如下三元组:

swp:BaronWayApartment swp:address "4 Baron Way Circle".

我们可能想要找所有在地址中包含 “4 Baron Way” 并且此字符串在开头的资源。

PREFIX swp: <http://www.semanticwebprimer.org/ontology/apartments.ttl#>.
PREFIX dbpedia: <http://dbpedia.org/resource/>.
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>.
SELECT ?apartment
WHERE {
?apartment swp:address ?address.
FILTER regex(?address,"^4 Baron Way").
}

最后一个常用的函数是 str它将资源和文字转换为可以在正则表达式中使用的字符串表示。例如,我们可以在资源的 URL 而不是标签中搜索 Baron, 如下所示:

PREFIX swp: <http://www.semanticwebprimer.org/ontology/apartments.ttl#>.
PREFIX dbpedia: <http://dbpedia.org/resource/>.
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>.
SELECT ?apartment ?address
WHERE {
?apartment swp:address ?address.
FILTER regex(str(?apartment), "Baron").
}

2.3 schema不同时的查询处理

由于数据库的不同,我们对一些属性的名称也不同,这时也需要我们能够查询到我们想要的信息。比如以下这个公寓的例子:

@prefix swp: <http://www.semanticwebprimer.org/ontology/apartments.ttl#>.
@prefix dbpedia: <http://dbpedia.org/resource/>.
@prefix dbpedia-owl: <http://dbpedia.org/ontology/>.
@prefix xsd: <http://www.w3.Org/2001/XMLSchema#>.

swp:BaronWayApartment swp:hasNumberOfBedrooms 3.
swp:BaronWayApartment dbpedia-owl:location dbpedia:Amsterdam.
swp:BaronWayApartment refs:label "Baron Way Apartment for Rent".

swp:FloridaAveStudio swp:hasNumberOfBedrooms 1.
swp:FloridaAveStudio dbpedia-owl:locationCity dbpedia:Amsterdam.

现在我们要查询位于Amsterdam的公寓,并且返回label(如果有):

PREFIX swp: <http://www.semanticwebprimer.org/ontology/apartments.ttl#>.
PREFIX geo: <http://www.geonames.org/ontology#>.
PREFIX dbpedia: <http://dbpedia.org/resource/>.
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>.

SELECT ?apartment ?label
WHERE {
	{?apartment dbpedia-owl:location dbpedia:Amsterdam.}
	UNION
	{?apartment dbpedia-owl:locationCity dbpedia:Amsterdam.}
	OPTIONAL
	{?apartment rdfs:label ?label.}
}

或者使用**|**运算符简化如上查询:

PREFIX swp: <http://www.semanticwebprimer.org/ontology/apartments.ttl#>.
PREFIX dbpedia: <http://dbpedia.org/resource/>.
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>.

SELECT ?apartment ?label
WHERE {
	{?apartment dbpedia-owl:location|dbpedia-owl:locationCity dbpedia:Amsterdam.}
	OPTIONAL
	{?apartment rdfs:label ?label.}
}

UNION 关键词告诉三元组存储库返回那些仅匹配一个图模式或两个都匹配的结果。
OPTIONAL 关键词告诉三元组存储库为特定的图模式返回结果——如果能找到。即对于待返回的査询而言,这个图模式未必要被满足。因此,在这个例子中, 如果没有这个可选项,这间单间公寓就不会在査询结果中返回。

查询结果如下:

?apartment

?label

swp:BaronWayApartment

Baron Way Apartment for Rent

swp:FloridaAveStudio

2.4 结果组织

一种常见的情况是,我们想要査询结果以一种特定的方式返回:分组的、 计数的或排序
的。 SPARQL 支持一些函数来帮助我们组织结果集。我们已经知道了如何使用LIMIT 关键词来限制结果的数量。我们也可以使用DISTINCT 关键词,把它放在选择关键词之后(例如SELECT DISTINCT ?name WHERE), 来消除结果集中的重复结果。这将确保返回互不相同的变量绑定。

SPARQL 也允许使用 ORDER BY 关键词来对返回的结果集排序。例如,我们可以要求公寓按卧室数量排序。

比如:

SELECT ?apartment ?bedrooms
WHERE {
	?apartment swprhasNumberOfBedrooms ?bedrooms.
}
ORDER BY DESC(?bedrooms)

DESC降序,ASC升序。
也可以返回平均数,和,最大值等等,比如以下求数据集中平均卧室数量:

PREFIX swp: <http://www.semanticwebprimer.org/ontol0gy/apartments.ttl#>.
PREFIX dbpedia: <http://dbpedia.org/resource/>.
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>.
SELECT (AVG(?bedrooms) AS ?avgNumRooms)
WHERE {
?apartment swp:hasNumberOfBedrooms ?bedrooms.
}

返回结果是:

avgNumRooms

2

2.5 其他形式的SPARQL查询

到目前为止,我们已经关注了从一个 RDF 集合中选择特定的值。 SPARQL 也支持一些其他形式的査询。除了 SELECT 以外,两种常用的查询是** ASK** 和 CONSTRUCT

ASK 形式的査询简单地检査一个数据集中是否存在一个图模式,而不是去返回结果。使用 ASK 査询的原因是,比起检索一个完整的结果集, ASK 査询计算得更快。例如,下面这个查询将返回真。

PREFIX swp: <http://www.semanticwebprimer.org/ontology/apartments.ttl#> •
PREFIX dbpedia: <http://dbpedia.org/resource/>.
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>.
ASK ?apartment
WHERE {
	?apartment swp:hasNumberOfBedrooms 3.
}

CONSTRUCT 形式的查询用来从一个更大的 RDF 集中检索出一个 RDF 图。例如,我们可以创建一个新图,将那些拥有超过 2 间卧室的公寓标记为大公寓。

PREFIX ex: <http://www.example.org/>
PREFIX dbpedia: <http://dbpedia.org/resource/>
PREFIX geo. <http://www.geonames.org/ontology#>
CONSTRUCT {?apartment swp:hasNumberOfBedrooms ?bedrooms. ?apartment swp:isBigApartment true.}
WHERE{
	?apartment swp:hasNumberOfBedrooms ?bedrooms.
}
FILTER (?bedrooms > 2)

返回结果如下:

@prefix swp: <http://www.semanticwebprimer.org/ontology/apartments.ttl#>.
@prefix dbpedia: <http://dbpedia.org/resource/>.
@prefix dbpedia-owl: <http://dbpedia.org/ontology/>.
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.

swp:BaronWayApartment swp:hasNumberOfBedrooms 3.
swp:BaronWayApartment swp:isBigApartment true.

2.6 通过SPARQL更新来增加信息

以下插入一个三元组,阐述 Luxury Apartment 是 Apartment 的一个子类。它将这个三元组加人三元组存储库的已有内容之中。

PREFIX swp: <http://www.semanticwebprimer.org/ontology/apartments.ttl#>.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
INSERT DATA
{
	swp:LuxuryApartment rdfs:subClassOf swp:Apartment.
}

如果你在万维网上有一个大的包含 RDF 的文件,你可以使用以下命令将它加载进一个三
元组存储库:

LOAD <http://example.com/apartment.rdf>

将之前插入的三元组删除可以这样:

PREFIX swp: <http://www.semanticwebprimer.org/ontology/apartments.ttl#>.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

DELETE DATA
{
	swp:LuxuryApartment rdfs:subClassOf swp:Apartment.
}

一种更加灵活的方式是使用 DELETE WHERE 构造子。它可以删除匹配指定图模式的那
些三元组。以下将要删除包含关于拥有超过 2 间卧室的公寓的信息的所有三元组。

PREFIX swp: <http://www.semanticwebprimer.org/ontology/apartments.ttl#>.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> ,
DELETE WHERE{
	?apartment swp:hasNumberOf6edrooms ?bedrooms.
FILTER (?bedrooms > 2)
}

最后,要删除一个三元组存储库中的所有内容,可以如下使用 CLEAR 构造子:

CLEAR ALL

三、知乎上的例子

RDF查询语言SPARQL

参考文献

《语义网基础教程》