查询语义网:SPARQL
一、概述
SPARQL是RDF的查询语言,适合并依赖于万维网上的各种技术。SPARQL能够让我们通过选择、抽取等方式从被表示为RDF的知识中获取特定的部分。
二、基础设施
三元组存储库(triple store),可以看做是RDF的数据库,也被称作图存储库。每个三元组存储库都提供一个端点(endpoint),客户端使用HTTP协议向端点发送查询。
三、匹配模式
在SPARQL中,将三元组中的任何一个元素替换为一个变量:变量的首字符是一个’?’,还要引入一个变量表示位置。比如想要查找某栋建筑的位置,可以表示为下面的方式:
swp:BaronWayBuilding dbpedia-owl:location ?location.
三元组存储库对该语句的处理过程如下:
- 接收这个图模式(graph pattern)
- 查找能够匹配这个模式的那些三元组集合,即所有以 swp:BaronWayBuilding作为主语,dbpedia-owl:location作为谓语的三元组。
上述只是一个SPARQL查询中的一部分,一个完整的查询还需要有全局信息,比如缩写、前缀的定义,以及查询变量的声明。将上述语句转化为完整的语句如下:
PREFIX swp: <http://www.semanticwebprimer.org/ontology/apartments.ttl#>.
PREFIX dbpedia: <http://www.dbpedia.org/resource/>.
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>.
SELECT ?location
WHERE {
swp:BaronWayBuilding dbpedia-owl:location ?location.
}
其中PREFIX关键词指明各种URL的缩写。 SELECT语句类似于SQL的查询语句。返回的查询结果是一组称作绑定(binding)的映射,表示哪些元素对应到一个给定的变量。
SPARQL还具有变量的传递功能:
···
SELECT ?location
WHERE {
swp:BaronWayApartment swp:isPartOf ?building
?building dbpedia-owl:location ?location.
}
重用变量名?building,可以将两个三元组进行连接。在不知道直接对应的RDF时,这种方式查询可以查找到最终的结果。
此外还可以进行多变量的查询,在SELECT后面添加所有需要查询的变量:
···
SELECT ?p ?o
WHERE {
swp:BaronWayApartment swp:isPartOf ?p.
?p dbpedia-owl:location ?o.
}
SPARQL还提供了属性路径,是一种精确表述属性链的方式。
原始的语句:
?apartment swp:isPartOf ?building.
?building dbpedia-owl:location dbpedia:Amsterdam.
用属性路径表述为:
?apartment swp:isPartOf/dbpedia-owl:location dbpedia:Amsterdam.
四、过滤器
当处理如大于或小于一个特定数量的查询时,可以使用FILTER关键字。该关键字支持数值型数据类型(即整型数、小数以及日期/时间等)。
其相应的语法方式如下:
···
SELECT ?apartment
WHERE {
?apartment swp:hasNumberOfBedrooms ?bedrooms.
FILTER(?bedrooms >2).
}
此外,FILTER还支持字符串的过滤,采用SPARQL内置的正则表达式(regex)实现。
···
SELECT ?apartment
WHERE {
?apartment swp:address ?address.
FILTER regex(?address, "^4 Baron Way")
}
五、其它
组织结果集:类似于SQL中的一些关键词,包括DISTINCT、ORDER BY,以及聚集函数COUNT、SUM、MIN、MAX、AVG等。
SELECT (?apartment ?bedrooms AVG(?bedrooms) AS ?avgNumRooms)
WHERE {
?apartment swp:hasNumberOfBedrooms ?bedrooms
}
OREDER BY DESC(?bedrooms)
ASK查询:简单地检查一个数据集中是否存在一个图模式,如果存在则返回真。
ASK ?apartment
WHERE {
?apartment swp:hasNumberOfBedrooms 3.
}
CONSTRUCT查询:从一个更大的RDF集中检索出一个RDF图。CONSTRUCT查询经常用来在模式(schema)之间转换–_通过查询特定的模式,并用目标模式中的属性替换。
···
CONSTRUCT {?apartment swp:hasNumberOfBedrooms ?bedrooms. ?apartment swp:isBigApartment true.}
WHERE {
?apartment swp:hasNumberOfBedrooms ?bedrooms.
FILTER(?bedrooms >2).
}
其查询结果将返回一个图:
swp:BaronWayApartment swp:hasNumberOfBedrooms 3.
swp:BaronWayApartment swp:isBigApartment true.
增删数据:使用命令INSERT DATA和DELETE DATA。
六、利用SPARQL查询
在之前构造rdf文件时,已经定义了Graph模型,现在调用模型可以对相应的RDF文件查询,输出相应的三元组。
首先输入已知知识,用’,'分隔,未知的元素直接空缺,输入后用split进行拆分。
print("输入查询的三元组,用','分隔:")
Subject, Predicate, Object = input().split(',')
转换完成后,根据不同的输入情况构造查询语句q:
if Subject != '' and Predicate == '' and Object == '':
q = "select ?Predicate ?Object where { <" + subject_config + Subject + "> ?Predicate ?Object }"
result = mygraph.query(q)
for i in range(len(list(result))):
s = str(list(result)[i])
data = postprocessing(s)
data.insert(0,Subject)
print(data[0], data[1] + ':', data[2])
elif Subject != '' and Predicate != '' and Object == '':
q = "select ?Object where {<" + subject_config + Subject + "> <" + predicate_config + Predicate + "> ?Object}"
result = mygraph.query(q)
for i in range(len(list(result))):
s = str(list(result)[i])
data = postprocessing(s)
data.insert(0,Subject)
data.insert(1,Predicate)
print(data[0], data[1] + ':', data[2])
···
其中graph.query函数进行查询之后的结果是一个SPARQLResult类型的变量,需要再进行一个后处理,提取其中的关键信息,使得输出易于理解。
def postprocessing(in_str):
txt = re.findall(base_config + r'.*?\'', in_str) # 切分出相关元素
rt = []
for item in txt:
temp = item.replace(base_config, '').replace('\'','') # 去除多余的'
rt.append(temp)
return rt
查询结果:
仅有主语:
仅有宾语:
通过主语和关系查询宾语:
七、总结
- SPARQL通过匹配图模式来选择信息,并提供基于数值和字符串比较的过滤机制。
- SPARQL查询采用类似Turtle的语法。
- 数据和模式(schema)都可以使用SPARQL来查询。
- UNION和OPTIONAL构造子允许SPARQL更容易地处理开放世界数据。
- SPARQL更新提供了从三元组存储库中更新和删除信息的机制。