SPARQL——语义网的查询语言

官方文档:SPARQL 1.1 Query Language

0. 前言

SPARQL语言主要是面向RDF/OWL的查询语言。从图论的角度来看,查询的过程可以看做子图匹配。相应的案例采用python实现。在python中,操作本体的库是rdflib,这个库非常好用,rdflib的官方教程也非常容易看懂和上手。

数据的准备就是把Data文件复制到记事本里面,然后将txt文件的后缀名修改成为.ttl或者.rdf就可以了。

1. 开始熟悉SPARQL

1.1 开始最简单的查询——使用SPARQL查询TTL文件

数据准备:

@prefix dc: <http://www.semanticweb.org/mayn/ontologies/2020/09/test#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xml: <http://www.w3.org/XML/1998/namespace> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

dc:a  dc:name   "Johnny Lee Outlaw" .
dc:a  dc:mbox   <mailto:jlow@example.com> .
dc:b  dc:name   "Peter Goodguy" .
dc:b  dc:mbox   <mailto:peter@example.org> .
dc:c  dc:mbox   <mailto:carol@example.org> .
dc:a  dc:age  "42"^^xsd:integer .
dc:b  dc:age  "25"^^xsd:integer .
dc:c  dc:age  "36"^^xsd:integer .
dc:a  dc:has  "cat"@en .
_:a  dc:name   "Alice" .
_:b  dc:name   "Bob" .

查询代码:

from rdflib import Graph
g = Graph()
g.parse("data 1-1.ttl", format = 'ttl')      
q = '''SELECT ?name {dc:a  dc:name ?name .}'''
rows = g.query(q)

使用rdflib来操作本体并采用SPARQL查询的程序框架如上所示。在这段程序中,我们首先新建了一个图g,然后从数据文件中将本体数据导入这个图中。q是SPARQL查询语句,通过g.query(q)获取查询结果。

SELECT{}是最常用的SPARQL查询语句。?x定义了一个变量,变量可以用?或者$开头,?x$x指代同一个变量。{}给这个变量限制了一些条件。上面这段查询语句的意思就是查询a的姓名,返回结果就是Johnny Lee Outlaw。SPARQL匹配到的结果又被称为解决方案(Solutions)。

我们可以一次查询多个变量,或者设置多个限制条件——

q = '''SELECT ?name ?mail{
    ?x dc:name ?name .
    ?x dc:mbox ?mail .
    }
    '''
rows = g.query(q)
for row in rows:
    print("%s has mail %s" %row)

查询结果:

Johnny Lee Outlaw has mail mailto:jlow@example.com
Peter Goodguy has mail mailto:peter@example.org

上面这个案例就是同时查找人的名字及其邮箱。需要注意的是,当出现多个限制条件是,除了最后一个限制条件,其余的每个限制条件都要以.结尾。为了避免语法错误,建议每个条件的结尾都加上.。在SPARQL中,可以出现很多个中间变量(如上例中的?x),来帮助完成不同指定变量(?name?mail)之间的逻辑构建,这些中间变量如果不SELECT出来,是不会出现在查询结果中的。

SPARQL也可以用于空白节点(Blank Node)的查询。

print('-'*15)    
q = '''SELECT ?x ?name{
    ?x dc:name ?name .
    }
    '''
rows = g.query(q)
for row in rows:
    print("%s 's name is %s" %row)

查询结果:

f3e668e8003a54a8eb9636271b8e3046ab2 's name is Bob
f3e668e8003a54a8eb9636271b8e3046ab1 's name is Alice
http://www.semanticweb.org/mayn/ontologies/2020/09/test#a 's name is Johnny Lee Outlaw
http://www.semanticweb.org/mayn/ontologies/2020/09/test#b 's name is Peter Goodguy

对于空白节点,会随机分配地址。

可以看到,

1.2 使用SPARQL查询RDF文件

Data(1-2):

@prefix dt:   <http://example.org/datatype#> .
@prefix ns:   <http://example.org/ns#> .
@prefix :     <http://example.org/ns#> .
@prefix xsd:  <http://www.w3.org/2001/XMLSchema#> .

:x   ns:p     "cat"@en .
:y   ns:p     "42"^^xsd:integer .
:z   ns:p     "abc"^^dt:specialDatatype .
_:a  ns:name   "Alice" .
_:b  ns:name   "Bob" .

对于指明数据类型的变量查找

在RDF文件中,我们可以看到有些属性被赋予了数据类型,比如:x ns:p "cat"@en .说明x是词典中的单词"cat",语言是英文;:y ns:p "42"^^xsd:integer .表明y的某个属性数值是42,类型是整型;:z ns:p "abc"^^dt:specialDatatype .说明z的属性是abc,类型是规定的特殊类型。

对于这种指明了数据的RDF文件,在查询时同样需要指明数据类型:

SELECT ?v WHERE { 
?v ?p "cat"@en . 
}

如果查询语句是SELECT ?v WHERE { ?v ?p "cat" }的话,将无法得到正确的结果。

对于数值型的变量查找

如果是对于数值型的变量查找,可以有两种表述方式:

  • SELECT ?v WHERE { ?v ?p "42"^^xsd:integer . }
  • SELECT ?v WHERE { ?v ?p 42 . }

总的来说,SPARQL中有以下几种LIiteral描述方式:

类型描述案例
字符串型“chat”
词典型(lexical)'chat'@fr 该例子表明词典的语言是法语
自定义数据类型"xyz"^^<http://example.org/ns/userDatatype>
时间"abc"^^appNS:appDataType
引号套用——如果字符串中包括双引号,则用三引号描述。'''The librarian said, "Perhaps you would enjoy 'War and Peace'." '''
整型1 或者 "1"^^xsd:integer
一位小数1.3 或者 "1.3"^^xsd:decimal
多位小数1.300 或者 "1.300"^^xsd:decimal
科学计数法1.0e6 或者 "1.0e6"^^xsd:double
布尔值(真)true 或者 "true"^^xsd:boolean
布尔值 (假)false 或者 "false"^^xsd:boolean

1.3 三元组的构建语法

SPARQL通过构建一系列的三元组来进行匹配。SPARQL中的三元组的基本语法和ttl或者rdf文件中的一致。在构建这些三元组时,SPARQL有一些特殊的语法技巧:

  1. 对一个主语(subject)的多条约束
    如果要实现对一个主语的多条约束,可以用分号;隔开。比如下面这两个语句是等价的。
?x  foaf:name  ?name ;
    foaf:mbox  ?mbox .
?x  foaf:name  ?name .
?x  foaf:mbox  ?mbox .
  1. 匹配多个宾语(objects)
    如果多个三元组的主语和谓语都是一样的,则可以用逗号,将宾语合并,形成一个三元组。下表中对应的两组三元组是等价的:
三元组1三元组2
?x foaf:nick “Alice” , “Alice_” .?x foaf:nick “Alice” .
?x foaf:nick “Alice_” .
?x foaf:name ?name ;
foaf:nick “Alice” , “Alice_” .
?x foaf:name ?name .
?x foaf:nick “Alice” .
?x foaf:nick “Alice_” .
  1. RDF Collections
    如果要检索RDF Collections三元组,则可以用(element1 element2 ...)的格式。这种格式还可以嵌套使用。官方文档给了2个案例来帮助理解。

  2. rdf:type
    在SPARQL中,可以用谓语a来代替谓语rdf:type。比如?x a :Class1 .?x rdf:type :Class1 .是一个意思。

2. SPARQL的匹配模式

SPARQL是基于图形模式来匹配的,第二章主要介绍以下几种不同的匹配模式。

匹配模式匹配逻辑关键字
Basic Graph Patterns匹配所有满足条件的变量SELECT
Group Graph Patterns匹配所有满足WHERE条件及FILTER条件的变量(类似于逻辑语言中的AND)SELECT WHERE FILTER
Optional Graph patterns提供可选择的匹配条件,如果满足OPTIONAL条件,则返回OPTIONAL相关的结果;OPTIONAL中的条件不影响其他变量的匹配。OPTIONAL
Alternative Graph Pattern匹配UNION条件中的任意一个,即可得到结果,类似于逻辑语言中的OR;如果UNION所有的条件均不满足,则无法匹配。UNION
Negation主要是对匹配结果的筛选FILTER NOT EXISTS / FILTER EXISTS / MINUS
Patterns on Named Graphs匹配指定命名空间中的三元组FROM

2.1 Basic Graph Patterns (SELECT)

@prefix dc: <http://www.semanticweb.org/mayn/ontologies/2020/09/test#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xml: <http://www.w3.org/XML/1998/namespace> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

dc:a  dc:name   "Johnny Lee Outlaw" .
dc:a  dc:mbox   <mailto:jlow@example.com> .
dc:b  dc:name   "Peter Goodguy" .
dc:b  dc:mbox   <mailto:peter@example.org> .
dc:c  dc:mbox   <mailto:carol@example.org> .
dc:a  dc:age  "42"^^xsd:integer .
dc:b  dc:age  "25"^^xsd:integer .
dc:c  dc:age  "36"^^xsd:integer .

比如,我们要获取本体中的所有三元组,可以使用下面这条查询语句:

SELECT *  {?s ?p ?o .}

关于SELECT WHERE{}的案例在第一章中已经有很多,在此不做赘述。

2.2 Group Graph Patterns (SELECT WHERE FILTER)

Group Graph Patterns在Basic Graph Patterns的基础上增加了对结果的过滤条件。比如,我们想要知道本体中年龄大于30的人,可以用下面这条查询语句,过滤条件用FILTER ()来实现:

SELECT ?x WHERE{
	?x dc:age ?age .
	FILTER (?age >30)
}

匹配结果:

http://www.semanticweb.org/mayn/ontologies/2020/09/test#c
http://www.semanticweb.org/mayn/ontologies/2020/09/test#a

如果要过滤包含字符串的结果,则用FILTER regex (element1, element2)来实现:

SELECT ?x WHERE{
	?x dc:name ?name .
	FILTER regex(?name, "Lee")
}

匹配结果:

http://www.semanticweb.org/mayn/ontologies/2020/09/test#a

2.3 Optional Graph patterns (OPTIONAL)

Optional matching provides this facility: if the optional part does not match, it creates no bindings but does not eliminate the solution.

OPTIONAL用于指定可选的匹配条件。比如下面这组匹配模式,?x dc:mbox ?mail .是必须满足的条件,?x dc:name ?name .是选择满足的条件。运行下面的匹配模式,可以得到三个结果。而如果不添加OPTIONAL条件,则只能得到两个结果。

SELECT ?x ?name ?mail WHERE{
	?x dc:mbox ?mail .
	OPTIONAL{?x dc:name ?name .}
}

匹配结果:

http://www.semanticweb.org/mayn/ontologies/2020/09/test#b Peter Goodguy mailto:peter@example.org
http://www.semanticweb.org/mayn/ontologies/2020/09/test#a Johnny Lee Outlaw mailto:jlow@example.com
http://www.semanticweb.org/mayn/ontologies/2020/09/test#c None mailto:carol@example.org
SELECT ?x ?name ?mail WHERE{
	?x dc:mbox ?mail .
	?x dc:name ?name .
}

匹配结果:

http://www.semanticweb.org/mayn/ontologies/2020/09/test#b Peter Goodguy mailto:peter@example.org
http://www.semanticweb.org/mayn/ontologies/2020/09/test#a Johnny Lee Outlaw mailto:jlow@example.com

同时,也可以在OPTIONAL条件中添加限制条件:

SELECT ?x ?name ?age WHERE{
	?x dc:name ?name .
	OPTIONAL{
        	?x dc:age ?age .
        	FILTER(?age > 30)
        	}
}

匹配结果:

http://www.semanticweb.org/mayn/ontologies/2020/09/test#a Johnny Lee Outlaw 42
http://www.semanticweb.org/mayn/ontologies/2020/09/test#b Peter Goodguy None

当然,可以有多个OPTIONAL条件:

SELECT ?x ?name ?mail ?age WHERE{
	?x dc:mbox ?mail .
	OPTIONAL{?x dc:name ?name .}
	OPTIONAL{?x dc:age ?age .}
}

匹配结果:

http://www.semanticweb.org/mayn/ontologies/2020/09/test#a Johnny Lee Outlaw mailto:jlow@example.com 42
http://www.semanticweb.org/mayn/ontologies/2020/09/test#b Peter Goodguy mailto:peter@example.org 25
http://www.semanticweb.org/mayn/ontologies/2020/09/test#c None mailto:carol@example.org 36

需要注意的是,OPTIONALleft-associative的。我的理解就是它只限制它对的前一个三元组所匹配得到的结果,并不是对整个查询模式的匹配。

2.4 Alternative Graph Pattern (UNION)

Alternative Graph Pattern通过UNION来实现。

数据准备:

@prefix dc10:  <http://purl.org/dc/elements/1.0/> .
@prefix dc11:  <http://purl.org/dc/elements/1.1/> .

_:a  dc10:title     "SPARQL Query Language Tutorial" .
_:a  dc10:creator   "Alice" .

_:b  dc11:title     "SPARQL Protocol Tutorial" .
_:b  dc11:creator   "Bob" .

_:c  dc10:title     "SPARQL" .
_:c  dc11:title     "SPARQL (updated)" .

查询代码:

SELECT ?title WHERE  {
	 { ?book dc10:title  ?title } UNION { ?book dc11:title  ?title } 
}

匹配结果:

SPARQL Query Language Tutorial
SPARQL
SPARQL Protocol Tutorial
SPARQL (updated)

可以使用多个UNION来联合不同的条件:

SELECT ?x ?y ?z WHERE{ 
	{ ?book dc10:title ?x } UNION { ?book dc11:title  ?y } UNION {?book dc10:creator ?z}
}

匹配结果:

SPARQL Query Language Tutorial None None
SPARQL None None
None SPARQL Protocol Tutorial None
None SPARQL (updated) None
None None Alice
SELECT ?title ?author WHERE  {
	{ ?book dc10:title ?title .  ?book dc10:creator ?author }
	UNION
	{ ?book dc11:title ?title .  ?book dc11:creator ?author }
}

匹配结果:

SPARQL Query Language Tutorial Alice
SPARQL Protocol Tutorial Bob

2.5 Negation (FILTER NOT EXISTS/ FILTER EXISTS/ MINUS)

Negation主要是对匹配结果的筛选。首先。FILTER NOT EXISTS筛选出不符合相关条件的变量。比如下面这组模式,匹配的是有邮箱但是没有名字的变量,匹配结果是http://www.semanticweb.org/mayn/ontologies/2020/09/test#c。在实际的应用中,FILTER NOT EXISTS在本体或者知识图谱的查漏这方面有比较大的发挥空间。

SELECT ?x WHERE{
	?x dc:mbox ?mail .
	FILTER NOT EXISTS {?x dc:name ?name .}
}

匹配结果:

http://www.semanticweb.org/mayn/ontologies/2020/09/test#c

我们也可以通过FILTER EXISTS来找到那些既有邮箱,又有姓名的人。

SELECT ?x WHERE{
	?x dc:mbox ?mail .
	FILTER EXISTS {?x dc:name ?name .}
}

匹配结果:

http://www.semanticweb.org/mayn/ontologies/2020/09/test#a
http://www.semanticweb.org/mayn/ontologies/2020/09/test#b

使用FILTER实际上是对整个匹配模型进行了筛选。SPARQL同样提供了left-associative的关键字——MINUS

SELECT ?x WHERE{
	?x dc:mbox ?mail .
	MINUS {?x dc:name "Johnny Lee Outlaw" .}
}

匹配结果:

http://www.semanticweb.org/mayn/ontologies/2020/09/test#c
http://www.semanticweb.org/mayn/ontologies/2020/09/test#b

FILTER和MINUS是两种不同的删减思路,他们主要的区别在官网中有比较清晰的描述。主要从以下三个方面来理解:

  • Sharing of variables

数据:
在这里插入图片描述

匹配模式匹配结果
在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述

对于FILTER NOT EXISTS来说,虽然其条件中的变量?x ?y ?z和外层的?s ?p ?o不一样,但是他们的匹配模式是相同的,所以筛选出不符合{?x ?y ?z}的结果,返回没有匹配。而MINUS条件中的变量名和外层的条件中没有匹配,所以删减的是变量名为{?x ?y ?z}的模式,结果就是啥都没有删减。

用一句话来概括就是,MINUS内外参数共享,而FILTER NOT EXISTS内外参数不共享。如果能理解这个,后面两个就能很好地理解了。

  • Fixed pattern
匹配模式匹配结果
在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述
  • Inner FILTERs

数据:
在这里插入图片描述

匹配模式匹配结果
在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述

3. SPARQL中的属性路径(Property Path)

属性路径提供了更加灵活的匹配模式。属性路径(Property Path)是图中两个节点之间的关系集合。SPARQL中关于属性路径的语法如下表所示,其中iri表示前缀(命名空间的全称或者缩写),elt表示路径元素。计算优先级从高到低,1表示最高;同一级的运算按照从左至右进行。

Property Path 类型语法格式匹配逻辑计算优先级
PredicatePathiriAn IRI. A path of length one.1
NegatedPropertySet!iri或者!(iri1| ...|irin)路径中不包含相关的匹配。需要注意的是,!iri!(iri)并不等价。2
NegatedPropertySet!^iri或者!(^iri1| ...|^irin)反向路径中不包含相关的匹配。!^iri!(^iri)并不等价。2
NegatedPropertySet!(iri1| ...|irij|^irij+1| ...|^irin)前面两种否定形式的结合。2
组合路径 Groups(elt)路径组合3
ZeroOrMorePathelt*匹配0个以上路径元素elt4
OneOrMorePathelt+匹配1个以上路径元素elt4
ZeroOrOnePathelt?匹配0个或1个路径元素elt4
InversePath^elt表示路径的反方向5
SequencePathelt1 / elt2匹配路径序列(elt1elt26
AlternativePathelt1 | elt2匹配路径中的任意一个(elt1 or elt27

4. Assignment:给匹配变量重新赋值(BIND / VALUES)

数据准备:

@prefix dc:   <http://purl.org/dc/elements/1.1/> .
@prefix :     <http://example.org/book/> .
@prefix ns:   <http://example.org/ns#> .

:book1  dc:title     "SPARQL Tutorial" .
:book1  ns:price     42 .
:book1  ns:discount  0.2 .

:book2  dc:title     "The Semantic Web" .
:book2  ns:price     23 .
:book2  ns:discount  0.25 .

BIND——给变量赋值

SELECT  ?title ?price{  
	?x ns:price ?p .
	?x ns:discount ?discount
	BIND (?p*(1-?discount) AS ?price)
	?x dc:title ?title . 
}

匹配结果:

The Semantic Web, 17.25
SPARQL Tutorial, 33.6

我们可以看到,利用关键字BIND可以将运算结果重新赋予变量?price

VALUES——限制变量的取值范围

SELECT ?book ?title ?price{
	VALUES ?book { :book1 :book3 }
	?book dc:title ?title ;
     	  ns:price ?price .
}

匹配结果:

http://example.org/book/book1, SPARQL Tutorial 42

这组匹配模式的意思是匹配变量?book,该变量的取值范围是{ :book1 :book3 },并输出其书名和价格。因为数据里面没有:book3,所以返回的结果只匹配了:book1

下面是另一个例子。

SELECT ?book ?title ?price
{
   ?book dc:title ?title ;
         ns:price ?price .
   VALUES (?book ?title)
   { (UNDEF "SPARQL Tutorial")
     (:book2 UNDEF)
   }
}

匹配结果:

http://example.org/book/book1, SPARQL Tutorial 42
http://example.org/book/book2, The Semantic Web 23

这里,关键字UNDEF表示对变量没有限制条件。这组匹配模式匹配的是书名为"SPARQL Tutorial"和书:book2的书名和价格。

5. Aggregates:整合匹配结果(GROUP BY / HAVING)

Aggregates用于对匹配结果的整合。一般来说,匹配结果默认会放在一起。如果我们希望能够得到分组结果,可以使用分组关键字GROUP BYHAVING。同时,可以使用COUNT, SUM, MIN, MAX, AVG, GROUP_CONCATSAMPLE等关键字对结果进行整合。、

数据准备:

@prefix : <http://books.example/> .

:org1 :affiliates :auth1, :auth2 .
:auth1 :writesBook :book1, :book2 .
:book1 :price 9 .
:book2 :price 5 .
:auth2 :writesBook :book3 .
:book3 :price 7 .
:org2 :affiliates :auth3 .
:auth3 :writesBook :book4 .
:book4 :price 7 .

查询代码:

SELECT ?org (SUM(?lprice) AS ?totalPrice)
    WHERE{
            ?org :affiliates ?auth .
            ?auth :writesBook ?book .
            ?book :price ?lprice .
        }
    GROUP BY ?org

匹配结果:

http://books.example/org1 21
http://books.example/org2 7

可以看到,这组匹配模式匹配的是书的价格总和,并且按照机构?org来分组。在SELECT条件中,虽然出现了?lprice变量,但是通过(SUM(?lprice) AS ?totalPrice)?lprice变量的结果整合到了?totalPrice中,所以匹配结果中只有?org?totalPrice两个变量。

关键字HAVING相当于对组合结果的过滤(FILTER)。

SELECT ?org (SUM(?lprice) AS ?totalPrice)
    WHERE{
            ?org :affiliates ?auth .
            ?auth :writesBook ?book .
            ?book :price ?lprice .
        }
    GROUP BY ?org
    HAVING (SUM(?lprice) > 10)

匹配结果:

http://books.example/org1 21

6. SPARQL查询语句的嵌套

SPARQL查询语句SELECT是可以嵌套使用的。

数据准备:

@prefix : <http://people.example/> .

:alice :name "Alice", "Alice Foo", "A. Foo" .
:alice :knows :bob, :carol .
:bob :name "Bob", "Bob Bar", "B. Bar" .
:carol :name "Carol", "Carol Baz", "C. Baz" .

查询代码:

SELECT ?y ?minName
WHERE{
	:alice :knows ?y .
	{
		SELECT ?y (MIN(?name) AS ?minName)
		WHERE{
			?y :name ?name .
			} 
		GROUP BY ?y
		}
	}

匹配结果:

http://people.example/bob B. Bar
http://people.example/carol C. Baz

在上面这个匹配模式中,首先先执行内层的匹配模式SELECT ?y (MIN(?name) AS ?minName) WHERE{ ?y :name ?name . } GROUP BY ?y,得到以下三个结果(?y?minName):

http://people.example/bob B. Bar
http://people.example/carol C. Baz
http://people.example/alice A. Foo

然后在这个结果的基础上,执行外层的匹配模式SELECT ?y ?minName WHERE {:alice :knows ?y . }

7. 匹配Named Graph (FROM)

The default graph is defined as the union of all named graphs.
参考资料:SPARQL datasets and named graphs
参考资料:13 RDF Dataset

前面我们使用的SPARQL语句都是针对Default Graph的,如果我们要针对某一命名空间中的三元组(Named Graph)进行匹配,SPARQL查询可以通过使用FROM子句和FROM NAMED子句来指定用于匹配的数据集。

8. 对匹配结果进行修改和排序

匹配模式关键字匹配逻辑
OrderORDER BY对匹配结果进行排序
Projection选择特定的变量,即得到结果的子集。如果是SELECT *,那么返回的结果中会包含所有限制条件中出现的变量;如果是SELECT ?x,那么即使限制条件中出现了?y?z,最后的结果只会返回变量?x的匹配结果。这个过程就叫做Projection。
Duplicate SolutionsDISTINCT / REDUCED确保返回的结果中没有重复的选项
OffsetOFFSET返回从关键字OFFSET后指定的数字开始的匹配结果
LimitLIMIT限制返回的匹配结果的数量。如果把匹配结果看成是一个list,那么OFFSET num_1 LIMIT num_2相当于list[num1: num1 + num2]。

8.1 对匹配结果进行排序(ORDER BY)

数据准备:

@prefix dc: <http://www.semanticweb.org/mayn/ontologies/2020/09/test#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xml: <http://www.w3.org/XML/1998/namespace> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

dc:a  dc:name   "Johnny Lee Outlaw" .
dc:a  dc:mbox   <mailto:jlow@example.com> .
dc:b  dc:name   "Peter Goodguy" .
dc:b  dc:mbox   <mailto:peter@example.org> .
dc:c  dc:mbox   <mailto:carol@example.org> .
dc:a  dc:age  "25"^^xsd:integer .
dc:b  dc:age  "25"^^xsd:integer .
dc:c  dc:age  "36"^^xsd:integer .
dc:c  dc:name   "Carol" .

ORDER BY后面的语句是排序的依据。

例子排序逻辑匹配结果
SELECT ?name
WHERE{ ?x dc:name ?name . }
ORDER BY ?name
对匹配结果根据人名来排序。Carol
Johnny Lee Outlaw
Peter Goodguy
SELECT ?name
WHERE{ ?x dc:name ?name . ?x dc:age ?age . }
ORDER BY ASC(?age)
关键字DESC表示降序,ASC表示升序。这组匹配模式的匹配结果将根据年龄从低到高输出人名。Peter Goodguy
Johnny Lee Outlaw
Carol
SELECT ?name
WHERE{ ?x dc:name ?name . ?x dc:age ?age . }
ORDER BY ?age DESC(?name)
这里有两个限制条件,首先,先按照年龄排序,对于相同年龄的人,按照姓名进行逆序排列。Peter Goodguy
Johnny Lee Outlaw
Carol

对于不同的数据类型,SPARQL也规定了比较方法:numerics(数值型 <simple literals < xsd:strings < xsd:booleans < xsd:dateTimes。当然,有些RDF数据在SPARQL中是没有办法被比较的:

在这里插入图片描述

8.2 确保匹配结果不重复——DISTINCT / REDUCED

数据

@prefix  foaf:  <http://xmlns.com/foaf/0.1/> .

_:x    foaf:name   "Alice" .
_:x    foaf:mbox   <mailto:alice@example.com> .

_:y    foaf:name   "Alice" .
_:y    foaf:mbox   <mailto:asmith@example.com> .

_:z    foaf:name   "Alice" .
_:z    foaf:mbox   <mailto:alice.smith@example.com> .
匹配模式匹配结果
在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述

9. SPARQL的查询形式(Query Forms)

Query Forms应用场景
SELECTReturns all, or a subset of, the variables bound in a query pattern match.
CONSTRUCTReturns an RDF graph constructed by substituting variables in a set of triple templates. 类似于SWRL中的(?x p1 ?y)→ (?x p2 ?y)
ASKReturns a boolean indicating whether a query pattern matches or not. 可用于判断某个/类三元组是否存在,对于知识图谱的查漏比较有用。
DESCRIBEReturns an RDF graph that describes the resources found.
  • 8
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值