用 SPARQL 搜索 RDF 数据2.docx

上传人:b****8 文档编号:9919855 上传时间:2023-02-07 格式:DOCX 页数:17 大小:40.44KB
下载 相关 举报
用 SPARQL 搜索 RDF 数据2.docx_第1页
第1页 / 共17页
用 SPARQL 搜索 RDF 数据2.docx_第2页
第2页 / 共17页
用 SPARQL 搜索 RDF 数据2.docx_第3页
第3页 / 共17页
用 SPARQL 搜索 RDF 数据2.docx_第4页
第4页 / 共17页
用 SPARQL 搜索 RDF 数据2.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

用 SPARQL 搜索 RDF 数据2.docx

《用 SPARQL 搜索 RDF 数据2.docx》由会员分享,可在线阅读,更多相关《用 SPARQL 搜索 RDF 数据2.docx(17页珍藏版)》请在冰豆网上搜索。

用 SPARQL 搜索 RDF 数据2.docx

用SPARQL搜索RDF数据2

用SPARQL搜索RDF数据

用SPARQL和Jena工具包开启语义Web

级别:

初级

PhilMcCarthy(phil@),软件开发顾问,MocruxneyLtd.

2005年6月13日

随着越来越多的数据使用类似RSS的RDF格式保存,一种新的需求产生了,即要求用一种简单方法查找特定信息。

SPARQL这个功能强大的新查询语言填补了这个空白,使用户可以很容易地在RDF的杂草从中找到所需的数据。

本文将和您一起查看SPARQL的特性,学习如何利用Jena语义Web工具包,在自己的Java应用程序中使用SPARQL查询。

资源描述框架(ResourceDescriptionFramework),或RDF,能够将数据打散并分布开来。

RDF模型可以容易地合并在一起,而且序列化的RDF也可以简单地通过HTTP交换。

应用程序可以通过Web松散地耦合到多个RDF数据源上。

例如,在PlanetRDF.com上,我们把多个作者的weblog集中起来,作者们在RSS1.0feed中用RDF提供内容。

作者feed的URL本身就放在RDF图中,叫作bloggers.rdf。

但是怎样才能在RDF图中发现并操纵需要的数据呢?

SPARQL协议和RDF查询语言(SPARQL)目前是W3C的工作草案,还在讨论当中。

SPARQL构建在以前的RDF查询语言(例如rdfDB、RDQL和SeRQL)之上,拥有一些有价值的新特性。

在本文中,我们将用三种驱动PlanetRDF的RDF图——描述作者的FOAF图、他们的RSS1.0feed以及bloggers图——来演示SPARQL能对数据做的一些有意思的事情。

SPARQL拥有针对各种平台和语言的实现;本文将重点介绍面向Java平台的Jena语义Web工具包。

本文假设您有RDF的工作知识,熟悉RDF的词汇(例如DublinCore、FOAF和RSS1.0)。

此外,本文还假设您有一些使用Jena语义Web工具包的经验。

要想跟上所有这些技术的发展速度,请参阅后面参考资料部分中的链接。

一个简单SPARQL查询的剖析

我们首先从查看PlanetRDF的bloggers.rdf模型开始。

该模型非常简单,通过FOAF和DublinCore词汇为每个blog投稿者提供名称、blog标题和URL。

图1显示了一个投稿者的基本图结构。

完整的模型只是为我们汇集的每一篇blog日志重复这个结构而已。

图1.bloggers.rdf中的一个投稿者的基本图结构

现在,我们来看一个针对博客模型的非常简单的SPARQL查询。

比方说以下这个查询“根据名为JonFoobar的人查找blog的URL”,如清单1所示:

清单1.查找某一投稿者的blog的URL的SPARQL查询

PREFIXfoaf:

<

SELECT?

url

FROM

WHERE{

?

contributorfoaf:

name"JonFoobar".

?

contributorfoaf:

weblog?

url.

}

查询的第一行只是为FOAF定义PREFIX,这样就不必每次都用完整名称引用它。

SELECT子句指定查询应当返回的内容,在这个例子中,返回的是名为url的变量。

SPARQL变量用?

或$作为前缀,这两个前缀是可以互换的,但在本文中,我坚持使用?

作为前缀。

FROM是一个可选的子句,它提供了将要使用的数据集的URI。

在这里,它只是指向一个本地文件,但是它也可以指向Web其他地方的某一个图的URL。

最后,WHERE子句由一组三元模式组成,用基于Turtle的语法表示。

这些三元模式共同构成了所谓的图形模式。

这个查询试图把图形模式的三元模式和模型进行匹配。

将每个图形模式变量的绑定与模型节点进行匹配就成为一种查询解决方案,而SELECT子句中指定的变量值则成为查询结果的一部分。

在这个示例中,WHERE子句的图形模式中的第一个三元组与foaf:

name属性为“JonFoobar”的节点匹配,并把它绑定到名为contributor的变量。

在bloggers.rdf模型中,contributor会和图1顶部的空节点foaf:

Agent匹配。

图形模式的第二个三元组与contributor的foaf:

weblog属性对应的对象匹配。

这被绑定到url变量,形成查询结果。

在Jena中使用SPARQL

支持在Jena中使用SPARQL目前可以通过叫作ARQ的模块得以实现。

除了实现SPARQL之外,ARQ的查询引擎还可以解析使用RDQL或者它自己内部的查询语言表示的查询。

ARQ的开发很活跃,但它还不是标准Jena发行版本中的一部分。

但是,可以从Jena的CVS仓库或者自包含的下载文件中获得它。

让ARQ运行起来很简单。

只需要得到最新的ARQ发行包(要获得有关链接,请参阅后面参考资料部分),然后对其进行解压,把环境变量ARQROOT设置成指向ARQ目录即可。

可能还需要恢复ARQbin目录的读取和执行权限。

如果把bin目录添加到执行路径中非常方便,那是因为它包含从命令行调用ARQ的包装器脚本。

为了确定所有设置都已到位,请从命令行调用sparql,确定看到了它的用法信息。

清单2演示了所有步骤,清单2假设正在UNIX类的平台上工作,或者是在Windows下用Cygwin工作。

(ARQ还附带了在Windows下使用的.bat脚本,但是它们用法和下面示例中的用法稍有差别。

清单2.设置使用JenaARQ的环境

$exportARQROOT=~/ARQ-0.9.5

$chmod+rx$ARQROOT/bin/*

$exportPATH=$PATH:

$ARQROOT/bin

$sparql

Usage:

[--dataURL][exprString|--queryfile]

从命令行执行SPARQL查询

现在就可以运行SPARQL查询了(参见清单3)。

我们将使用来自清单1的数据集和查询。

因为查询使用FROM关键字指定要使用的图,所以只需把查询文件的位置提供给sparql命令行即可。

但是,查询需要在包含图的目录中运行,因为该图是在查询的FROM子句中用相对URL指定的。

清单3.用sparql命令执行简单查询

$sparql--queryjon-url.rq

----------------------------

|url|

============================

|

//foobar.xx/blog>|

----------------------------

有时,从查询中忽略FROM子句很有意义。

这样就可以允许在执行查询的时候才把图传递给它。

当从应用程序代码中使用SPARQL时,避免把数据集绑定到查询是一个好习惯——例如,它允许把同一查询重用在不同的图上。

可以在命令行用sparql--dataURL选项在运行时指定图,其中URL是图的位置。

这个URL既可以是本地文件的位置,也可以是远程图的Web地址。

用JenaAPI执行SPARQL查询

命令行sparql工具对于运行独立查询有用,同时Java应用程序也可以直接调用Jena的SPARQL功能。

通过com.hp.hpl.jena.query包中的类,使用Jena来创建和执行SPARQL查询。

使用QueryFactory是最简单的方法。

QueryFactory有各种create()方法,用来从文件或者String读取文本查询。

这些create()方法返回Query对象,这个对象封装了解析后的查询。

下一步是创建QueryExecution的实例,这个类表示查询的一个执行。

要获得QueryExecution,请调用QueryExecutionFactory.create(query,model),并传入要执行的Query以及查询要处理的Model。

因为查询的数据是编程方式提供的,所以查询不需要FROM子句。

QueryExecution上有几种不同的执行方法,每个方法执行一种不同类型的查询(请参阅标题为“其他类型的SPARQL查询”的侧栏,以获得更多信息)。

对于简单的SELECT查询,可以调用execSelect(),该方法将返回ResultSet。

ResultSet支持在查询返回的每个QuerySolution上进行迭代,这提供了对每个绑定变量值的访问。

另外,还可以使用ResultSetFormatter,以不同的格式输出查询结果。

清单4显示了一个把这些步骤放在一起的简单方法。

它执行一个针对bloggers.rdf的查询,并把结果输出到控制台。

清间4.用JenaAPI执行一个简单查询

//OpenthebloggersRDFgraphfromthefilesystem

InputStreamin=newFileInputStream(newFile("bloggers.rdf"));

//Createanemptyin-memorymodelandpopulateitfromthegraph

Modelmodel=ModelFactory.createMemModelMaker().createModel();

model.read(in,null);//nullbaseURI,sincemodelURIsareabsolute

in.close();

//Createanewquery

StringqueryString=

"PREFIXfoaf:

<"+

"SELECT?

url"+

"WHERE{"+

"?

contributorfoaf:

name\"JonFoobar\"."+

"?

contributorfoaf:

weblog?

url."+

"}";

Queryquery=QueryFactory.create(queryString);

//Executethequeryandobtainresults

QueryExecutionqe=QueryExecutionFactory.create(query,model);

ResultSetresults=qe.execSelect();

//Outputqueryresults

ResultSetFormatter.out(System.out,results,query);

//Important-freeupresourcesusedrunningthequery

qe.close();

编写更复杂的查询

迄今为止,您已经看到了两种运行简单SPARQL查询的方法:

用命令行sparql工具,用Java代码调用JenaAPI。

在这一节中,我将介绍更多SPARQL的特性,以及它们支持的更复杂的查询。

RDF经常被用来表示半结构化的数据。

这意味着在一个模型中,两个相同类型的节点可能有两个不同的属性集。

例如,在FOAF模型中,对人的描述可能只包含电子邮件地址;而作为另一个选择,它也可以包含真实名称、IRC昵称、描绘个人照片的URL,等等。

提炼查询结果

为了进一步提炼查询的结果,SPARQL拥有DISTINCT、LIMIT、OFFSET和ORDERBY关键字,它们操作或多或少与它们在SQL中的对应物有些类似。

DISTINCT可能只用在SELECT查询上,格式为SELECTDISTINCT。

它会从结果集中清除重复的查询结果,让留下的每个结果都是惟一的。

其他关键字都放在查询的WHERE子句之后。

LIMITn把查询返回的结果数量限制在n个,而OFFSETn则忽略前面n个结果。

ORDERBY?

var会根据?

var的自然顺序对结果进行排序,例如,如果var是字符串值,则按字母顺序排序。

可以用ASC[?

var]和DESC[?

var]指定排序的方向。

当然,可以把DISTINCT、LIMIT、OFFSET和ORDERBY组合在查询中。

例如,可以用ORDERBYDESC[?

date]LIMIT10找到RSSfeed中最新的十个条目。

清单5显示了一个非常小的FOAF图,用Turtle语法表示。

它包含对4个虚构人物的描述,但是每个描述都有不同的属性集。

清单5.一个描述4个虚构人物的小FOAF图

@prefixfoaf:

<.

_:

afoaf:

name"JonFoobar";

foaf:

mbox

jon@foobar.xx>;

foaf:

depiction

//foobar.xx/2005/04/jon.jpg>.

_:

bfoaf:

name"A.N.O'Ther";

foaf:

mbox

a.n.other@>;

foaf:

depiction<.

_:

cfoaf:

name"LizSomebody";

foaf:

mbox_sha1sum"3f01fa9929df769aff173f57dec2fe0c2290aeea"

_:

dfoaf:

name"MBenn";

foaf:

depiction

//mbe.nn/pics/me.jpeg>.

可选匹配

假设您想编写一个查询,返回清单5的图中所描述的每个人的名字,以及每个人的照片的链接(如果有照片的话)。

在foaf:

depiction中包含的图形模式的SELECT查询可能只会发现三个结果。

LizSomebody不会形成结果,因为虽然它有foaf:

name属性,但它没有foaf:

depiction属性,而如果要与查询匹配的话,那么这两个属性都需要。

帮助就在眼前,就是SPARQL的OPTIONAL关键字。

可选块定义了附加图形模式,即使模式不匹配,不会造成结果被拒绝,但在匹配的时候,图形模式会被绑定到图形上。

清单6演示了一个查询,在清单5的FOAF数据中查找每个人的foaf:

name,而且可以选择性地查找伴随的foaf:

depiction。

清单6.用可选块查询FOAF数据

PREFIXfoaf:

<

SELECT?

name?

depiction

WHERE{

?

personfoaf:

name?

name.

OPTIONAL{

?

personfoaf:

depiction?

depiction.

}.

}

清单7显示了运行清单6的查询的结果。

所有查询结果都包含人名,可选的图形模式则只在foaf:

depiction属性存在的时候才绑定;如果没有,就从结果中忽略。

从这种意义上说,查询与SQL中的左外连接相似。

清单7.清单6的查询结果

------------------------------------------------------------

|name|depiction|

============================================================

|"A.N.O'Ther"|<|

|"JonFoobar"|

//foobar.xx/2005/04/jon.jpg>|

|"LizSomebody"||

|"MBenn"|

//mbe.nn/pics/me.jpeg>|

------------------------------------------------------------

可选块可以包含任何图形模式,不仅仅是像清单6所示的那种单一的三元模式。

可选块中的所有查询模式都匹配,才能让可选模式成为查询结果的一部分。

如果查询有多个可选块,那么它们会分别发挥作用——可能在结果中被忽略,也可能存在于结果中。

可选块也可以嵌套,在这种情况下,只有外部可选块的模式与图形匹配时,才考虑内部可选块。

替换匹配

FOAF图形用人们的电子邮件地址来惟一地标识他们。

出于隐私的考虑,有些人喜欢用电子邮件地址的哈希码。

纯文本的电子邮件地址用foaf:

mbox属性表示,而电子邮件地址的哈希码则用foaf:

mbox_sha1sum属性表示;这两个属性在人们的FOAF描述中通常是互斥的。

在这种情况下,可以用SPARQL的替代匹配特性来编写查询,该查询返回任何可用的属性。

替换匹配的定义方式是写出多个替换图形模式,中间用UNION关键字连接。

清单8显示的查询在清单5中的FOAF中查找每个人的名字,以及他们的foaf:

mbox或foaf:

mbox_sha1sum。

MBenn不是查询结果,因为它既没有foaf:

mbox属性也没有foaf:

mbox_sha1sum属性。

与OPTIONAL图形模式相比,至少要有一个替换模式和某个查询结果匹配;如果UNION匹配中的分支都匹配,那么会生成两个结果。

清单8.有替代匹配的查询和查询结果

PREFIXfoaf:

<

PREFIXrdf:

//www.w3.org/1999/02/22-rdf-syntax-ns#>

SELECT?

name?

mbox

WHERE{

?

personfoaf:

name?

name.

{

{?

personfoaf:

mbox?

mbox}UNION{?

personfoaf:

mbox_sha1sum?

mbox}

}

}

---------------------------------------------------------------------

|name|mbox|

=====================================================================

|"JonFoobar"|

jon@foobar.xx>|

|"A.N.O'Ther"|

a.n.other@>|

|"LizSomebody"|"3f01fa9929df769aff173f57dec2fe0c2290aeea"|

---------------------------------------------------------------------

值约束条件

SPARQL中的FILTER关键字对绑定变量的值进行约束,从而限制查询的结果。

这些值约束条件是对布尔值进行计算的逻辑表达式,并且可以与逻辑操作符&&和||组合使用。

例如,可以用过滤器把返回名称列表的查询修改成只返回和指定正则表达式匹配的名称。

或者,如清单9所示,过滤器在项目的出版日期上设置限制,从而找到RSSfeed中在两个特定日期之间发布的项目。

清单9还显示了如何使用SPARQL的XPath样式的类型转换特性(在这里,是将date变量转换成XMLSchema的dateTime值),以及如何用^^xsd:

dateTime在文字日期字符串上指定相同的数据类型。

这可以确保在查询中使用日期比较,而不是标准的字符串比较。

清单9.用过滤器检索在2005年4月发布的RSSfeed项目

PREFIXrss:

//purl.org/rss/1.0/>

PREFIXxsd:

//www.w3.org/2001/XMLSchema#>

PREFIXdc:

//purl.org/dc/elements/1.1/>

SELECT?

item_title?

pub_date

WHERE{

?

itemrss:

title?

item_title.

?

itemdc:

date?

pub_date.

FILTERxsd:

dateTime(?

pub_date)>="2005-04-01T00:

00:

00Z"^^xsd:

dateTime&&

xsd:

dateTime(?

pub_date)<"2005-05-01T00:

00:

00Z"^^xsd:

dateTime

}

处理多个图形

迄今为止,我所演示的所有查询只包含一个RDF图的数据集。

在SPARQL的术语中,这些查询针对的是后台图(backgroundgraph)。

后台图是指:

在使用Jena的API时,通过某个查询的FROM子句、sparql命令的--data开关或者通过向QueryExecutionFactory.create()传递一个模型来指定的图。

其他类型的SPARQL查询

除了本文使用的SELECT查询之外,SPARQL还支持另外三种查询。

如果查询的图形模式在数据集中有匹配物,那么ASK将返回“yes”,如果没有匹配物,则返回“no”。

DESCRIBE返回一个图形,其中包含和图形模式匹配的节点的相关信息。

例如,DESCRIBE?

personWHERE{?

personfoaf:

name"JonFoobar"}会返回一个图,其中包括来自JonFoobar的模型的三元模式。

最后,CONSTRUCT用来为每个查询结果输出一个图形模式。

这样就可以直接从查询结果创建新的RDF图。

可以把RDF图上的CONSTRUCT查询想像成与XML数据的XSL转换类似的东西。

除了后台图,SPARQL还能查询任意数量的命名图。

这些附加的图是根据它们的URI来识别的,而这些URI在一个查询内是互不相同的。

在研

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 文学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1