精华内容
下载资源
问答
  • SparQL

    千次阅读 2019-03-20 15:59:26
    SPARQL(SPARQL Protocol and RDF Query Language),是为RDF开发的一种查询语言和数据获取协议,它是为W3C所开发的RDF数据模型所定义,但是可以用于任何可以用RDF来表示的信息资源。SPARQL 协议和 RDF 查询语言...

    SPARQL (SPARQL Protocol and RDF Query Language),是为RDF开发的一种查询语言和数据获取协议,它是为W3C所开发的RDF数据模型所定义,但是可以用于任何可以用RDF来表示的信息资源。SPARQL 协议和 RDF 查询语言(SPARQL)于2008年1月15日正式成为一项W3C推荐标准。SPARQL构建在以前的 RDF 查询语言(例如 rdfDB、RDQL 和 SeRQL)之上,拥有一些有价值的新特性。

    优点

    SPARQL允许用户针对可以被称为“键值”数据的内容,或者更具体地说,遵循W3C的RDF规范的数据来编写查询。因此,整个数据库是一组“主语 - 谓语 - 对象”三元组。这类似于一些NoSQL数据库对术语“文档键值”的使用,例如MongoDB。

    在SQL关系数据库术语中,RDF数据也可以被视为具有三列的表 - 主题列,谓词列和对象列。 RDF中的主题类似于SQL数据库中的实体,其中给定业务对象的数据元素(或字段)放置在多个列中,有时分布在多个表中,并由唯一键标识。在RDF中,这些字段表示为共享相同主题的单独谓词/对象行,通常是相同的唯一键,谓词类似于列名称,对象是实际数据。与关系数据库不同,对象列是异构的:每单元数据类型通常由谓词值暗示(或在本体中指定)。与SQL不同,RDF每个谓词可以有多个条目;例如,可以为单个“人”提供多个“子”条目,并且可以返回这些对象的集合,例如“儿童”。

    因此,SPARQL为数据提供了一整套分析查询操作,例如JOIN,SORT,AGGREGATE,这些数据的模式本质上是数据的一部分,而不需要单独的模式定义。但是,架构信息(本体)通常在外部提供,以允许明确地连接不同的数据集。此外,SPARQL为可以将其视为图形的数据提供特定的图形遍历语法。

    下面的示例演示了一个利用本体定义foaf(“朋友的朋友”)的简单查询。具体来说,以下查询返回数据集中每个人的姓名和电子邮件:

    PREFIX foaf: <http://xmlns.com/foaf/0.1/>
    SELECT ?name        ?email WHERE  {    ?person  a          foaf:Person .    ?person  foaf:name  ?name .    ?person  foaf:mbox  ?email .  }

    此查询将所有三元组与一个匹配的主题连接在一起,其中类型谓词“a”是一个人(foaf:Person),并且该人具有一个或多个名称(foaf:name)和邮箱(foaf:mbox) )。

    此查询的作者选择使用变量名称“?person”来引用主题,以便于阅读。由于三元组的第一个元素始终是主语,因此作者可以轻松使用任何变量名称,例如“?subj”或“?x”。无论选择何种名称,在查询的每一行上都必须相同,以表示查询引擎要加入具有相同主题的三元组

    连接的结果是一组行 - ?person,?name,?email。此查询返回?name和?email,因为?person通常是复杂的URI而不是人性化的字符串。请注意,任何?人可能有多个邮箱,因此在返回的集中,?name行可能会多次出现,每个邮箱一次。

    此查询可以分发到多个SPARQL端点(接受SPARQL查询和返回结果的服务),计算和收集的结果,这个过程称为联合查询。

    无论是以联合方式还是本地方式,查询中的其他三重定义可以允许连接到不同的主题类型(例如汽车),以允许简单查询,例如,为驱动高速汽车的人返回名称和电子邮件列表燃油效率。

    查询表格

    对于从数据库读取数据的查询,SPARQL语言为不同目的指定了四种不同的查询变体。

    SELECT查询:用于从SPARQL端点提取原始值,结果以表格格式返回。

    CONSTRUCT查询:用于从SPARQL端点提取信息并将结果转换为有效的RDF。

    ASK查询:用于为SPARQL端点上的查询提供简单的True / False结果。

    DESCRIBE查询:用于从SPARQL端点提取RDF图,其内容留给端点根据维护者认为有用的信息来决定。

    这些查询表单中的每一个都使用WHERE块来限制查询,但是,在DESCRIBE查询的情况下,WHERE是可选的。

    例子

    另一个SPARQL查询示例模拟了“非洲所有国家/地区的资本是什么?”的问题:

    1

    PREFIX ex: <http://example.com/exampleOntology#>SELECT ?capital        ?countryWHERE  {    ?x  ex:cityname       ?capital   ;        ex:isCapitalOf    ?y         .    ?y  ex:countryname    ?country   ;        ex:isInContinent  ex:Africa  .  }

    变量用“?”表示 或“$”前缀。 将返回?capital和?country的绑定。

    SPARQL查询处理器将搜索与这四种三元模式匹配的三元组集,将查询中的变量绑定到每个三元组的相应部分。 这里要注意的重要一点是“属性方向”。为了使查询简洁,SPARQL允许以类似于Turtle的方式定义前缀和基URI。

    展开全文
  • SPARQL

    2012-04-22 15:25:02
    随着越来越多的数据使用类似 RSS 的 RDF 格式保存,一种新的需求产生了,...本文将和您一起查看 SPARQL 的特性,学习如何利用 Jena 语义 Web 工具包,在自己的 Java 应用程序中使用 SPARQL 查询。 http://www....
    随着越来越多的数据使用类似 RSS 的 RDF 格式保存,一种新的需求产生了,即要求用一种简单方法查找特定信息。SPARQL 这个功能强大的新查询语言填补了这个空白,使用户可以很容易地在 RDF 的杂草从中找到所需的数据。本文将和您一起查看 SPARQL 的特性,学习如何利用 Jena 语义 Web 工具包,在自己的 Java 应用程序中使用 SPARQL 查询。


    http://www.ibm.com/developerworks/cn/java/j-sparql/
    资源描述框架(Resource Description Framework),或 RDF,能够将数据打散并分布开来。RDF 模型可以容易地合并在一起,而且序列化的 RDF 也可以简单地通过 HTTP 交换。应用程序可以通过 Web 松散地耦合到多个 RDF 数据源上。例如,在 PlanetRDF.com 上,我们把多个作者的 weblog 集中起来,作者们在 RSS 1.0 feed 中用 RDF 提供内容。作者 feed 的 URL 本身就放在 RDF 图中,叫作 bloggers.rdf。

    但是怎样才能在 RDF 图中发现并操纵需要的数据呢?SPARQL 协议和 RDF 查询语言(SPARQL)目前是 W3C 的工作草案,还在讨论当中。SPARQL 构建在以前的 RDF 查询语言(例如 rdfDB、RDQL 和 SeRQL)之上,拥有一些有价值的新特性。在本文中,我们将用三种驱动 PlanetRDF 的 RDF 图 —— 描述作者的 FOAF 图、他们的 RSS 1.0 feed 以及 bloggers 图 —— 来演示 SPARQL 能对数据做的一些有意思的事情。SPARQL 拥有针对各种平台和语言的实现;本文将重点介绍面向 Java 平台的 Jena 语义 Web 工具包。

    本文假设您有 RDF 的工作知识,熟悉 RDF 的词汇(例如 Dublin Core、FOAF 和 RSS 1.0)。此外,本文还假设您有一些使用 Jena 语义 Web 工具包的经验。要想跟上所有这些技术的发展速度,请参阅后面 参考资料 部分中的链接。

    一个简单 SPARQL 查询的剖析

    我们首先从查看 PlanetRDF 的 bloggers.rdf 模型开始。该模型非常简单,通过 FOAF 和 Dublin Core 词汇为每个 blog 投稿者提供名称、blog 标题和 URL。图 1 显示了一个投稿者的基本图结构。完整的模型只是为我们汇集的每一篇 blog 日志重复这个结构而已。


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


    现在,我们来看一个针对博客模型的非常简单的 SPARQL 查询。比方说以下这个查询“根据名为 Jon Foobar 的人查找 blog 的 URL”,如清单 1 所示:


    清单 1. 查找某一投稿者的 blog 的 URL 的 SPARQL 查询
    PREFIX foaf: <http://xmlns.com/foaf/0.1/>
    SELECT ?url
    FROM <bloggers.rdf>
    WHERE {
    ?contributor foaf:name "Jon Foobar" .
    ?contributor foaf:weblog ?url .
    }




    查询的第一行只是为 FOAF 定义 PREFIX,这样就不必每次都用完整名称引用它。SELECT 子句指定查询应当返回的内容,在这个例子中,返回的是名为 url 的变量。SPARQL 变量用 ? 或 $作为前缀,这两个前缀是可以互换的,但在本文中,我坚持使用 ? 作为前缀。FROM 是一个可选的子句,它提供了将要使用的数据集的 URI。在这里,它只是指向一个本地文件,但是它也可以指向 Web 其他地方的某一个图的 URL。最后,WHERE 子句由一组三元模式组成,用基于 Turtle 的语法表示。这些三元模式共同构成了所谓的图形模式。

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

    在这个示例中,WHERE 子句的图形模式中的第一个三元组与 foaf:name 属性为“Jon Foobar”的节点匹配,并把它绑定到名为 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 目录即可。可能还需要恢复 ARQ bin 目录的读取和执行权限。如果把 bin 目录添加到执行路径中非常方便,那是因为它包含从命令行调用 ARQ 的包装器脚本。为了确定所有设置都已到位,请从命令行调用 sparql,确定看到了它的用法信息。清单 2 演示了所有步骤,清单 2 假设正在 UNIX 类的平台上工作,或者是在 Windows 下用 Cygwin 工作。(ARQ 还附带了在 Windows 下使用的.bat 脚本,但是它们用法和下面示例中的用法稍有差别。)


    清单 2. 设置使用 Jena ARQ 的环境
    $ export ARQROOT=~/ARQ-0.9.5
    $ chmod +rx $ARQROOT/bin/*
    $ export PATH=$PATH:$ARQROOT/bin
    $ sparql
    Usage: [--data URL] [exprString | --query file]




    从命令行执行 SPARQL 查询

    现在就可以运行 SPARQL 查询了(参见清单 3)。我们将使用来自 清单 1的数据集和查询。因为查询使用 FROM 关键字指定要使用的图,所以只需把查询文件的位置提供给 sparql 命令行即可。但是,查询需要在包含图的目录中运行,因为该图是在查询的 FROM 子句中用相对 URL 指定的。


    清单 3. 用 sparql 命令执行简单查询
    $ sparql --query jon-url.rq
    ----------------------------
    | url |
    ============================
    | <http://foobar.xx/blog> |
    ----------------------------




    有时,从查询中忽略 FROM 子句很有意义。这样就可以允许在执行查询的时候才把图传递给它。当从应用程序代码中使用 SPARQL 时,避免把数据集绑定到查询是一个好习惯 —— 例如,它允许把同一查询重用在不同的图上。可以在命令行用 sparql --data URL 选项在运行时指定图,其中 URL 是图的位置。这个 URL 既可以是本地文件的位置,也可以是远程图的 Web 地址。

    用 Jena API 执行 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.用 Jena API 执行一个简单查询
    // Open the bloggers RDF graph from the filesystem
    InputStream in = new FileInputStream(new File("bloggers.rdf"));
    // Create an empty in-memory model and populate it from the graph
    Model model = ModelFactory.createMemModelMaker().createModel();
    model.read(in,null); // null base URI, since model URIs are absolute
    in.close();
    // Create a new query
    String queryString =
    "PREFIX foaf: <http://xmlns.com/foaf/0.1/> " +
    "SELECT ?url " +
    "WHERE {" +
    " ?contributor foaf:name \"Jon Foobar\" . " +
    " ?contributor foaf:weblog ?url . " +
    " }";
    Query query = QueryFactory.create(queryString);
    // Execute the query and obtain results
    QueryExecution qe = QueryExecutionFactory.create(query, model);
    ResultSet results = qe.execSelect();
    // Output query results
    ResultSetFormatter.out(System.out, results, query);
    // Important - free up resources used running the query
    qe.close();







    回页首



    编写更复杂的查询

    迄今为止,您已经看到了两种运行简单 SPARQL 查询的方法:用命令行 sparql 工具,用 Java 代码调用 Jena API。在这一节中,我将介绍更多 SPARQL 的特性,以及它们支持的更复杂的查询。

    RDF 经常被用来表示半结构化的 数据。这意味着在一个模型中,两个相同类型的节点可能有两个不同的属性集。例如,在 FOAF 模型中,对人的描述可能只包含电子邮件地址;而作为另一个选择,它也可以包含真实名称、IRC 昵称、描绘个人照片的 URL,等等。

    提炼查询结果

    为了进一步提炼查询的结果,SPARQL 拥有 DISTINCT、LIMIT、OFFSET 和 ORDER BY 关键字,它们操作或多或少与它们在 SQL 中的对应物有些类似。DISTINCT 可能只用在 SELECT 查询上,格式为 SELECT DISTINCT。它会从结果集中清除重复的查询结果,让留下的每个结果都是惟一的。其他关键字都放在查询的 WHERE 子句之后。LIMIT n 把查询返回的结果数量限制在 n 个, 而 OFFSET n 则忽略前面 n 个结果。ORDER BY ?var 会根据 ?var 的自然顺序对结果进行排序,例如,如果 var 是字符串值,则按字母顺序排序。可以用 ASC[?var] 和 DESC[?var] 指定排序的方向。

    当然,可以把 DISTINCT、LIMIT、OFFSET 和 ORDER BY 组合在查询中。例如,可以用 ORDER BY DESC[?date] LIMIT 10 找到 RSS feed 中最新的十个条目。


    清单 5 显示了一个非常小的 FOAF 图,用 Turtle 语法表示。它包含对 4 个虚构人物的描述,但是每个描述都有不同的属性集。


    清单 5. 一个描述 4 个虚构人物的小 FOAF 图
    @prefix foaf: <http://xmlns.com/foaf/0.1/> .
    _:a foaf:name "Jon Foobar" ;
    foaf:mbox <mailto:jon@foobar.xx> ;
    foaf:depiction <http://foobar.xx/2005/04/jon.jpg> .
    _:b foaf:name "A. N. O'Ther" ;
    foaf:mbox <mailto:a.n.other@example.net> ;
    foaf:depiction <http://example.net/photos/an-2005.jpg> .
    _:c foaf:name "Liz Somebody" ;
    foaf:mbox_sha1sum "3f01fa9929df769aff173f57dec2fe0c2290aeea"
    _:d foaf:name "M Benn" ;
    foaf:depiction <http://mbe.nn/pics/me.jpeg> .




    可选匹配

    假设您想编写一个查询,返回清单 5 的图中所描述的每个人的名字,以及每个人的照片的链接(如果有照片的话)。在 foaf:depiction 中包含的图形模式的 SELECT 查询可能只会发现三个结果。Liz Somebody 不会形成结果,因为虽然它有 foaf:name 属性,但它没有 foaf:depiction 属性,而如果要与查询匹配的话,那么这两个属性都需要。

    帮助就在眼前,就是 SPARQL 的 OPTIONAL 关键字。可选块 定义了附加图形模式,即使模式不匹配,不会造成结果被拒绝,但在匹配的时候,图形模式会被绑定到图形上。清单 6 演示了一个查询,在清单 5 的 FOAF 数据中查找每个人的 foaf:name,而且可以选择性地查找伴随的 foaf:depiction。


    清单 6. 用可选块查询 FOAF 数据
    PREFIX foaf: <http://xmlns.com/foaf/0.1/>
    SELECT ?name ?depiction
    WHERE {
    ?person foaf:name ?name .
    OPTIONAL {
    ?person foaf:depiction ?depiction .
    } .
    }




    清单 7 显示了运行清单 6 的查询的结果。所有查询结果都包含人名,可选的图形模式则只在 foaf:depiction 属性存在的时候才绑定;如果没有,就从结果中忽略。从这种意义上说,查询与 SQL 中的左外连接相似。


    清单 7. 清单 6 的查询结果
    ------------------------------------------------------------
    | name | depiction |
    ============================================================
    | "A. N. O'Ther" | <http://example.net/photos/an-2005.jpg> |
    | "Jon Foobar" | <http://foobar.xx/2005/04/jon.jpg> |
    | "Liz Somebody" | |
    | "M Benn" | <http://mbe.nn/pics/me.jpeg> |
    ------------------------------------------------------------




    可选块可以包含任何图形模式,不仅仅是像清单 6 所示的那种单一的三元模式。可选块中的所有查询模式都匹配,才能让可选模式成为查询结果的一部分。如果查询有多个可选块,那么它们会分别发挥作用 —— 可能在结果中被忽略,也可能存在于结果中。可选块也可以嵌套,在这种情况下,只有外部可选块的模式与图形匹配时,才考虑内部可选块。

    替换匹配

    FOAF 图形用人们的电子邮件地址来惟一地标识他们。出于隐私的考虑,有些人喜欢用电子邮件地址的哈希码。纯文本的电子邮件地址用 foaf:mbox 属性表示,而电子邮件地址的哈希码则用 foaf:mbox_sha1sum 属性表示;这两个属性在人们的 FOAF 描述中通常是互斥的。在这种情况下,可以用 SPARQL 的 替代匹配 特性来编写查询,该查询返回任何可用的属性。

    替换匹配的定义方式是写出多个替换图形模式,中间用 UNION 关键字连接。清单 8 显示的查询在 清单 5 中的 FOAF 中查找每个人的名字,以及他们的 foaf:mbox 或 foaf:mbox_sha1sum。M Benn 不是查询结果,因为它既没有 foaf:mbox 属性也没有 foaf:mbox_sha1sum 属性。与 OPTIONAL 图形模式相比,至少 要有一个替换模式和某个查询结果匹配;如果UNION 匹配中的分支都匹配,那么会生成两个结果。


    清单 8. 有替代匹配的查询和查询结果
    PREFIX foaf: <http://xmlns.com/foaf/0.1/>
    PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
    SELECT ?name ?mbox
    WHERE {
    ?person foaf:name ?name .
    {
    { ?person foaf:mbox ?mbox } UNION { ?person foaf:mbox_sha1sum ?mbox }
    }
    }
    ---------------------------------------------------------------------
    | name | mbox |
    =====================================================================
    | "Jon Foobar" | <mailto:jon@foobar.xx> |
    | "A. N. O'Ther" | <mailto:a.n.other@example.net> |
    | "Liz Somebody" | "3f01fa9929df769aff173f57dec2fe0c2290aeea" |
    ---------------------------------------------------------------------




    值约束条件

    SPARQL 中的 FILTER 关键字对绑定变量的值进行约束,从而限制查询的结果。这些值约束条件是对布尔值进行计算的逻辑表达式,并且可以与逻辑操作符 && 和 || 组合使用。例如,可以用过滤器把返回名称列表的查询修改成只返回和指定正则表达式匹配的名称。或者,如清单 9 所示,过滤器在项目的出版日期上设置限制,从而找到 RSS feed 中在两个特定日期之间发布的项目。清单 9 还显示了如何使用 SPARQL 的 XPath 样式的类型转换特性(在这里,是将 date 变量转换成 XML Schema 的 dateTime 值),以及如何用 ^^xsd:dateTime 在文字日期字符串上指定相同的数据类型。这可以确保在查询中使用日期比较,而不是标准的字符串比较。


    清单 9. 用过滤器检索在 2005 年 4 月发布的 RSS feed 项目
    PREFIX rss: <http://purl.org/rss/1.0/>
    PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
    PREFIX dc: <http://purl.org/dc/elements/1.1/>
    SELECT ?item_title ?pub_date
    WHERE {
    ?item rss:title ?item_title .
    ?item dc:date ?pub_date .
    FILTER xsd:dateTime(?pub_date) >= "2005-04-01T00:00:00Z"^^xsd:dateTime &&
    xsd:dateTime(?pub_date) < "2005-05-01T00:00:00Z"^^xsd:dateTime
    }







    回页首



    处理多个图形

    迄今为止,我所演示的所有查询只包含一个 RDF 图的数据集。在 SPARQL 的术语中,这些查询针对的是 后台图(background graph)。后台图是指:在使用 Jena 的 API 时,通过某个查询的 FROM 子句、sparql 命令的 --data 开关或者通过向 QueryExecutionFactory.create() 传递一个模型来指定的图。

    其他类型的 SPARQL 查询

    除了本文使用的 SELECT 查询之外,SPARQL 还支持另外三种查询。如果查询的图形模式在数据集中有匹配物,那么 ASK 将返回 “yes”,如果没有匹配物,则返回 “no”。DESCRIBE 返回一个图形,其中包含和图形模式匹配的节点的相关信息。例如,DESCRIBE ?person WHERE { ?person foaf:name "Jon Foobar" } 会返回一个图,其中包括来自 Jon Foobar 的模型的三元模式。最后,CONSTRUCT 用来为每个查询结果输出一个图形模式。这样就可以直接从查询结果创建新的 RDF 图。可以把 RDF 图上的 CONSTRUCT 查询想像成与 XML 数据的 XSL 转换类似的东西。


    除了后台图,SPARQL 还能查询任意数量的 命名图。这些附加的图是根据它们的 URI 来识别的,而这些 URI 在一个查询内是互不相同的。在研究使用命名图的方法之前,我要解释一下如何向查询提供这些 URI。与后台图一样,命名图可以在查询内部用 FROM NAMED <URI> 指定,在这里,是通过 URI 来指定图。另外,也可以用 --named URL 把命名图提供给 sparql 命令,URL 用于指定图的位置。最后,可以用 Jena 的 DataSetFactory 类指定要用编程方式查询的命名图。

    在 SPARQL 查询内部用 GRAPH 关键字调用命名图,后面是图的 URI 或变量名。这个关键字后面是要与图匹配的图形模式。

    在特定图中查找匹配

    当 GRAPH 关键字和图的 URI(或者已经绑定到图的 URI 的变量)一起使用时,图形模式就被应用到这个 URI 标识的任何图。如果在指定的图中发现匹配物,那么该匹配物就成为查询结果的一部分。在清单 10 中,有两个 FOAF 图被传递给查询。查询结果是在两个图中都可以发现的那些人的名字。注意,表示每个 FOAF 图的那些人的节点是空节点,它们的作用范围有限,只在包含它们的图中有效。这意味着表示同一个人的节点不能在查询的两个命名图中同时存在,所以必须用不同的变量 (x 和 y)来表示它们。


    清单 10. 查找在两个命名 FOAF 图中都描述的那些人的查询
    PREFIX foaf: <http://xmlns.com/foaf/0.1/>
    PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
    SELECT ?name
    FROM NAMED <jon-foaf.rdf>
    FROM NAMED <liz-foaf.rdf>
    WHERE {
    GRAPH <jon-foaf.rdf> {
    ?x rdf:type foaf:Person .
    ?x foaf:name ?name .
    } .
    GRAPH <liz-foaf.rdf> {
    ?y rdf:type foaf:Person .
    ?y foaf:name ?name .
    } .
    }




    查找包含某个模式的图

    使用 GRAPH 的另一种方法是在它后面跟一个未绑定变量。在这种情况下,图形模式被应用到查询可以使用的每个命名图中。如果模式和其中一个命名图匹配,那么这个图的 URI 就被绑定到 GRAPH 的变量上。清单 11 的 GRAPH 子句和提供给查询的命名图中的每个人员节点匹配。匹配的人名被绑定到 name 变量,而 graph_uri 变量绑定到与模式匹配的图的 URI 上。查询的结果也显示出来。有一个名称 A. N. O'Ther 被匹配了两次,因为在 jon-foaf.rdf 和 liz-foaf.rdf 中都描述了这个人。


    清单 11. 确定哪个图描述了不同的人
    PREFIX foaf: <http://xmlns.com/foaf/0.1/>
    PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
    SELECT ?name ?graph_uri
    FROM NAMED <jon-foaf.rdf>
    FROM NAMED <liz-foaf.rdf>
    WHERE {
    GRAPH ?graph_uri {
    ?x rdf:type foaf:Person .
    ?x foaf:name ?name .
    }
    }
    --------------------------------------------------------
    | name | graph_uri |
    ========================================================
    | "Liz Somebody" | <file://.../jon-foaf.rdf> |
    | "A. N. O'Ther" | <file://.../jon-foaf.rdf> |
    | "Jon Foobar" | <file://.../liz-foaf.rdf> |
    | "A. N. O'Ther" | <file://.../liz-foaf.rdf> |
    --------------------------------------------------------



    XML 格式的查询结果

    SPARQL 允许以 XML 格式返回查询结果,采用的格式叫作 SPARQL 变量绑定结果 XML 格式。这个用 schema 定义的格式是 RDF 查询和 XML 工具及库之间的桥梁。

    这项功能还有许多潜在用途。可以把 SPARQL 查询的结果通过 XSLT 转换成 Web 面或 RSS feed,通过 XPath 访问结果,或者把结果文件返回给 SOAP 或 AJAX 客户。要以 XML 格式返回查询结果,请使用 ResultSetFormatter.outputAsXML() 方法,或者在命令行指定 --results rs/xml。


    组合后台数据和命名图

    查询也可以把后台数据和命名图结合在一起使用。清单 12 用来自 PlanetRDF.com 的活动的聚合 RSS feed 作为后台数据,结合一个包含我自己的配置档案的命名图对它进行查询。我的想法是创建一个个性化的 feed,找到我认识的一些博客最新发表的十个贴子。查询的第一部分找到了 FOAF 文件中代表我的那些节点,然后找到了图中描述的、我认识的那些人的名字。第二部分在这些人创建的 RSS feed 中查找项目。最后,按照项目的创建时间对结果集进行排序,而且限制只返回十个结果。


    清单 12. 得到一个个性化的活跃的 PlanetRDF feed
    PREFIX foaf: <http://xmlns.com/foaf/0.1/>
    PREFIX rss: <http://purl.org/rss/1.0/>
    PREFIX dc: <http://purl.org/dc/elements/1.1/>
    SELECT ?title ?known_name ?link
    FROM <http://planetrdf.com/index.rdf>
    FROM NAMED <phil-foaf.rdf>
    WHERE {
    GRAPH <phil-foaf.rdf> {
    ?me foaf:name "Phil McCarthy" .
    ?me foaf:knows ?known_person .
    ?known_person foaf:name ?known_name .
    } .
    ?item dc:creator ?known_name .
    ?item rss:title ?title .
    ?item rss:link ?link .
    ?item dc:date ?date.
    }
    ORDER BY DESC[?date] LIMIT 10




    虽然这个查询只是返回标题、名称和 URL 的列表,但是更复杂的查询可以从匹配项目提取出所有数据。采用 SPARQL 的 XML 结果格式(请参阅标题为“XML 格式的查询结果”的侧栏)与 XSL 样式表结合,还可以创建博客日志的个性化的 HTML 视图,甚至生成另一个 RSS feed。





    回页首



    结束语

    本文中的示例应当有助于您理解 SPARQL 的基本特性和语法,以及它带给 RDF 应用程序的好处。还了解了SPARQL 如何在可选和可替换匹配的帮助下,让您了解真实的 RDF 图的半结构化特性。使用命名图的示例还显示了如何使用 SPARQL 组合多个图来启用查询选项。您还看到在 Java 代码中用 Jena API 运行 SPARQL 是多么简单。

    对于 SPARQL,还有更多这里可能没有介绍的内容,所以请利用下面的 参考资料 查找关于 SPARQL 特性的更多内容。请参阅 SPARQL 的规范,详细学习 SPARQL 的内置函数、操作符、查询格式和语法,或者参阅更多 SPARQL 查询示例。

    当然,学习 SPARQL 的最好方法是编写一些自己的查询。从 Web 上得到一些 RDF 数据,下载 Jena ARQ 模块,开始体验吧!


    参考资料

    您可以参阅本文在 developerWorks 全球站点上的 英文原文。


    “Jena 简介”,这篇文章的作者也是 Philip McCarthy (developerWorks,2004 年 6 月),文中提供了Jena 语义 Web 工具包的概述,包括 RDQL 查询语言的一些细节。


    最新版的 SPARQL specification 提供了 SPARQL 查询语法和功能的确切描述。


    Dave Beckett 做了一份紧凑的 SPARQL Language Quick Reference,可以打印出来贴在办公桌上。


    SPARQL Query Results XML Format 描述了“Query results in XML format”中讨论的结构格式。


    Jena SourceForge project 上有大量 Jena 语义 Web 工具包的文档和下载。


    Andy Seaborne 的 ARQ home page 上有关于从 CVS 获得 ARQ 的指导。最新的 ARQ 发行包可以在 ARQ's downloads 页上找到。


    SPARQLer 是 Jena 的 SPARQL 查询语言引擎的一个在线演示。可以用它来体验 SPARQL 查询。


    Dave Beckett 的 Rasqal RDF 查询库是一个开源的 C 库,支持 SPARQL,包含各种语言绑定。


    FOAF Project 是用机器可读的 RDF 词汇来描述一些人及他们之间关系的一个实验。FOAF Vocabulary Specification 定义了本文使用的 FOAF 术语。


    Dublin Core Metadata Element Set 是常用的元数据术语的一个标准集合。许多 RDF 词汇和格式都采用它,例如 FOAF 和 RSS 1.0。


    SPARQL 的图形模式是以 Turtle -- Terse RDF Triple Language 的语法为基础。


    PlanetRDF.com 汇集了语义 Web 社区中的一些开发人员的网络日志,提供了一个追踪该领域的发展的简便方法。这篇文章在示例中使用了 PlanetRDF 的 RSS feed 和 RDF blogroll。


    通过参与 developerWorks blogs 加入 developerWorks 社区。


    在 developerWorks Java 技术专区 中可以找到 Java 编程的各个方面的文章。


    请参阅 Developer Bookstore,以获得技术书籍的完整清单,其中包括数百本 Java 相关主题 的书籍。
    展开全文
  • sparql:Ruby SPARQL库-源码

    2021-03-22 03:57:57
    用于RDF.rb的SPARQL 这是的的实现。 特征 100%免费且不受限制的软件。 完整的解析和执行 SPARQL结果为 , , , 或HTML。 SPARQL CONSTRUCT或DESCRIBE基于格式进行了序列化,使用可用的RDF编写器扩展了Mime类型...
  • sparql-utils sparql-utils提供了一些方便的实用程序,可用于在Scala中处理SPARQL查询。 当前功能包括: 一个字符串内插器,用于在SPARQL中嵌入和正确格式化/转义Scala对象。 通过自动类型类派生将SPARQL SELECT...
  • RDF.rb的SPARQL客户端 这是的客户端的实现。 特征 使用SPARQL gem通过HTTP对任何与SPARQL 1.0 / 1.1兼容的端点执行查询,或者对RDF::Queryable实例执行查询。 为ASK , SELECT , DESCRIBE和CONSTRUCT查询提供查询...
  • ( autoload 'sparql-mode " sparql-mode.el " " Major mode for editing SPARQL files " t ) ( add-to-list 'auto-mode-alist '( " \\ .sparql$ " . sparql-mode)) ( add-to-list 'auto-mode-alist '( " \\ .rq$ " ...
  • sparql-doc支持用于记录sparql查询的标记,以及用于查询集合的程序包元数据。 这些功能将在下一节中介绍。 SPARQL文档扩展 sparql-doc处理您的SPARQL查询并查找注释。 与Javadoc,rdoc和类似工具一样,注释的内容...
  • SPARQL.ex Elixir的标准的实现。 它允许对数据结构执行SPARQL查询。 使用单独的程序包,可以针对SPARQL协议端点执行SPARQL查询。 API文档可在找到。 有关SPARQL.ex及其相关项目的指南和更多信息,请访问 。 当前...
  • Learning SPARQL

    2015-12-04 12:03:58
    Lean how to write sparql queries
  • SPARQL 1.2社区组 欢迎使用github存储库。 。
  • snap-sparql-api 解析SPARQL查询的API
  • gs-sparql 使用SPARQL进行图挖掘 资源描述框架(RDF),SPARQL协议和RDF查询语言(SPARQL)于大约十年前推出,以实现语义Web上灵活的无模式数据交换。 如今,数据科学家使用该框架作为可伸缩的图形表示形式,以集成...
  • 图形存储客户端 NodeJS SPARQL 客户端支持 SPARQL 1.1 Graph Store HTTP 协议和使用 Q 承诺的 SPARQL 1.1 协议
  • rdf-sparql-builder rdf-sparql-builder可帮助在JavaScript代码中构建查询。 通过方法链接,而不是易于出错的字符串连接,可以在不切换编程语言的情况下编写查询。 用于诸如命名节点和变量之类的术语。 用法 程序包...
  • SPARQL Tutorial

    2021-02-09 14:51:28
    目录前言1 JENA安装2 Data Format3 A First SPARQL Query4 Basic Patterns5 Filters6 Optional Information7 Alternatives in a Pattern8 Datasets 前言   本文是SPARQL官方入门教程,通过示例介绍SPARQL的主要...

    前言

      本文是SPARQL官方入门教程,通过示例介绍SPARQL的主要功能。SPARQL是一种查询语言,用于查询RDF结构的数据。虽然RDF数据具备推理性,但是SPARQL本身没有推理查询功能,它是面向数据的,只能查询数据中包含的信息。
    官方文档:sparql tutorial

    1 JENA安装

      本教程演示在windows 10系统下安装JENA。JENA官方下载地址:https://jena.apache.org/download/index.cgi#, 选择.zip文件,下载后解压即可。安装JENA的前提是安装了Java运行环境。解压后设置JENA环境变量。
      在系统的环境变量中新建变量JENA_HOME,如下图所示,变量值填写你的JENA解压地址。
    在这里插入图片描述
      然后在系统环境变量的“PATH”变量中添加值“;%JENA_HOME%\bat”。最后测试安装是否成功,在cmd终端中输入命令:sparql --version,将出现版本号信息:
    在这里插入图片描述

    2 Data Format

      首先我们要清楚待查询数据的结构。SPARQL是在RDF图上查询,一个RDF图就是一组三元组。在Jena数据库中将RDF图称为模型(models),将三元组称为陈述(statements)。有很多种协议用于描述RDF三元组,描述三元组的方式称为序列化(serialization)。用何种序列化方式并不重要,我们关心的是三元组本身内容。RDF\XML是一种序列化方式,但这种方式不适合人类阅读。我们采用另一种序列化方式:Turtle。本文使用的数据如下图所示,数据下载地址:vc-db-1.rdf,格式是RDF/XML。
    在这里插入图片描述

      使用Turtle方式描述上述图,得到如下文件内容:

    @prefix vCard:   <http://www.w3.org/2001/vcard-rdf/3.0#> .
    @prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
    
    <http://somewhere/MattJones/>  vCard:FN   "Matt Jones" .
    <http://somewhere/MattJones/>  vCard:N    _:b0 .
    _:b0  vCard:Family "Jones" .
    _:b0  vCard:Given  "Matthew" .
    
    <http://somewhere/RebeccaSmith/> vCard:FN    "Becky Smith" .
    <http://somewhere/RebeccaSmith/> vCard:N     _:b1 .
    _:b1 vCard:Family "Smith" .
    _:b1 vCard:Given  "Rebecca" .
    
    <http://somewhere/JohnSmith/>    vCard:FN    "John Smith" .
    <http://somewhere/JohnSmith/>    vCard:N     _:b2 .
    _:b2 vCard:Family "Smith" .
    _:b2 vCard:Given  "John"  .
    
    <http://somewhere/SarahJones/>   vCard:FN    "Sarah Jones" .
    <http://somewhere/SarahJones/>   vCard:N     _:b3 .
    _:b3 vCard:Family  "Jones" .
    _:b3 vCard:Given   "Sarah" .
    

      上述内容中行的顺序可以打乱,机器在读取数据时并不关心数据的位置,这样写只是为了方便人类阅读。下载上面的数据,保存到本地电脑中。
      本文在JENA安装目录下新建doc\Tutorial文件夹,将vc-db-1.rdf文件保存到该文件夹中。

    3 A First SPARQL Query

      本小节介绍一个简单的查询例子,并展示Jena数据库是如何执行查询过程的。
      查询的数据就是7.2节展示的数据,查询语句如下:

    SELECT ?x
    WHERE { ?x  <http://www.w3.org/2001/vcard-rdf/3.0#FN>  "John Smith" }
    

      这个语句来自q1.rq。“?”表示这是个变量,“x”是变量名。“<>”中的是一个URI,描述了一个资源地址。双引号中的内容表示字面量(literal)。Where从句中描述了一个RDF三元组,其中主体是要查询的变量,谓语和客体已经给出具体的值。JENA按照谓语和客体区数据库中查找对应的三元组,然后返回找到的三元组的主体。
      将这个查询语句保存为文件q1.rq,并保存到本地的doc/Tutorial文件夹下,也就是和7.2节的数据文件vc-db-1.rdf放一起。如下所示:
    在这里插入图片描述
      打开cmd终端,进入doc/Tutorial目录下,执行命令:

    sparql --data=vc-db-1.rdf --query=q1.rq
    

      出现如下内容:
    在这里插入图片描述
      图中的“x”对应查询语句中的“x”,下方的值就是返回的结果。Where从句中也可以只指定一个值,其他两个值都是变量,如下查询语句:

    SELECT ?x ?fname
    WHERE {?x  <http://www.w3.org/2001/vcard-rdf/3.0#FN>  ?fname}
    

      将上述语句保存为文件q-bp1.rq,放到doc/Tutorial目录下。在终端执行命令:

    sparql --data=vc-db-1.rdf --query=q-bp1.rq
    

      返回查询结果如下图。
    在这里插入图片描述

    4 Basic Patterns

      一个基本的pattern就是一组三元组pattern,即在where从句中可以有多个三元组。多个三元组中变量名相同的变量需要匹配同一个实体。如下的查询语句中,两个三元组中的变量y表示的是同一个实体。

    SELECT ?givenName
    WHERE
      { ?y  <http://www.w3.org/2001/vcard-rdf/3.0#Family>  "Smith" .
        ?y  <http://www.w3.org/2001/vcard-rdf/3.0#Given>  ?givenName .
      }
    

      将上述查询语句保存为文件q-bq2.rq,放到doc/Tutorial目录下。在终端执行命令:

    sparql --data=vc-db-1.rdf --query=q-bp2.rq
    

      返回查询结果如下图。
    在这里插入图片描述
      SPARQL支持URI简写,可将上面的查询语句改为如下形式:

    PREFIX vcard:      <http://www.w3.org/2001/vcard-rdf/3.0#>
    
    SELECT ?givenName
    WHERE
     { ?y vcard:Family "Smith" .
       ?y vcard:Given  ?givenName .
     }
    

      第一行表示用vcard代替http://www.w3.org/2001/vcard-rdf/3.0#。将上述查询语句保存为文件q-bq3.rq,放到doc/Tutorial目录下。在终端执行命令:sparql --data=vc-db-1.rdf --query=q-bp3.rq。
      同样也可以返回查询的中间节点,上述查询中的节点‘y’就是中间节点,只要在select从句中加上该变量名即可,如下所示:

    PREFIX vcard:      <http://www.w3.org/2001/vcard-rdf/3.0#>
    
    SELECT ?y ?givenName
    WHERE
     { ?y vcard:Family "Smith" .
       ?y vcard:Given  ?givenName .
     }
    

      将上述查询语句保存为文件q-bq4.rq,放到doc/Tutorial目录下。在终端执行命令:

    sparql --data=vc-db-1.rdf --query=q-bp4.rq
    

      返回查询结果如下图。
    在这里插入图片描述
      返回的结果中‘y’具有不同的值,这是因为这个变量在数据中是个空白节点,针对空白节点,系统自动安排变量值。即使是同一个空白节点,系统打印的变量值也是不同的。

    5 Filters

      本文讲解如何给返回结果加上限制条件。第一种是使用正则表达式对返回结果中的字符串作出限制。语法如下:

    FILTER regex(?x, "pattern" [, "flags"])
    

      Pattern表示给出的正则表达式,flag是可选项。给出如下查询语句:

    PREFIX vcard: <http://www.w3.org/2001/vcard-rdf/3.0#>
    
    SELECT ?g
    WHERE
    { ?y vcard:Given ?g .
      FILTER regex(?g, "r", "i") }
    

      “r”表示返回的字符串中需要包含字母“r”,“i”是一个flag,表示不区分字符串中的大小写。将上述查询语句保存为文件q-f1.rq,放到doc/Tutorial目录下。在终端执行命令:

    sparql --data=vc-db-1.rdf --query=q-f1.rq
    

      返回查询结果如下图。
    在这里插入图片描述
      第二种是按条件返回结果。我们使用新的数据集,在其中加入人物的年龄信息,部分内容如下所示:

    <rdf:RDF
      xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
      xmlns:vCard='http://www.w3.org/2001/vcard-rdf/3.0#'
      xmlns:info='http://somewhere/peopleInfo#'
       >
    
      <rdf:Description rdf:about="http://somewhere/JohnSmith">
        <vCard:FN>John Smith</vCard:FN>
        <info:age rdf:datatype='http://www.w3.org/2001/XMLSchema#integer'>25</info:age>
        <vCard:N rdf:parseType="Resource">
    	<vCard:Family>Smith</vCard:Family>
    	<vCard:Given>John</vCard:Given>
        </vCard:N>
      </rdf:Description>
    
      <rdf:Description rdf:about="http://somewhere/RebeccaSmith">
        <vCard:FN>Becky Smith</vCard:FN>
        <info:age rdf:datatype='http://www.w3.org/2001/XMLSchema#integer'>23</info:age>
        <vCard:N rdf:parseType="Resource">
    	<vCard:Family>Smith</vCard:Family>
    	<vCard:Given>Rebecca</vCard:Given>
        </vCard:N>
      </rdf:Description>
    
      <rdf:Description rdf:about="http://somewhere/SarahJones">
        <vCard:FN>Sarah Jones</vCard:FN>
        <vCard:N rdf:parseType="Resource">
    	<vCard:Family>Jones</vCard:Family>
    	<vCard:Given>Sarah</vCard:Given>
        </vCard:N>
      </rdf:Description>
    
      <rdf:Description rdf:about="http://somewhere/MattJones">
        <vCard:FN>Matt Jones</vCard:FN>
        <vCard:N
    	vCard:Family="Jones"
    	vCard:Given="Matthew"/>
      </rdf:Description>
    
    </rdf:RDF>
    

      我们查询所有年龄大于24岁的人,查询语句如下所示:

    PREFIX info: <http://somewhere/peopleInfo#>
    
    SELECT ?resource
    WHERE
      {
        ?resource info:age ?age .
        FILTER (?age >= 24)
      }
    

      将上述查询语句保存为文件q-f2.rq,放到doc/Tutorial目录下。在终端执行命令:

    sparql --data=vc-db-1.rdf --query=q-f2.rq
    

      返回查询结果如下图。
    在这里插入图片描述

    6 Optional Information

      RDF 是半结构化数据,RDF中不同的实体可能具有不同的属性。SPARQL可以查询RDF中存在的信息,但是在查询不存在的信息时并不会显示查询失败,也不会返回任何结果。可以使用Optional关键字,表示该查询是可选的,也就是当实体存在该属性时,就返回结果,不存在时就返回空。
      例如下面的查询语句:

    PREFIX info:    <http://somewhere/peopleInfo#>
    PREFIX vcard:   <http://www.w3.org/2001/vcard-rdf/3.0#>
    
    SELECT ?name ?age
    WHERE
    {
        ?person vcard:FN  ?name .
        OPTIONAL { ?person info:age ?age }
    }
    

      Optional后的三元组表示实体存在age属性时就返回该属性结果,不存在就返回空。将上述查询语句保存为文件q-opt1.rq,放到doc/Tutorial目录下。在终端执行命令:

    sparql --data=vc-db-2.rdf --query=q-opt1.rq
    

      返回查询结果如下图。
    在这里插入图片描述
      如果没有optional关键字,上述查询语句就不会返回没有age属性的实体。如下所示,删除optional后的查询语句:

    PREFIX info:   <http://somewhere/peopleInfo#>
    PREFIX vcard:  <http://www.w3.org/2001/vcard-rdf/3.0#>
    
    SELECT ?name ?age
    WHERE
    {
        ?person vcard:FN  ?name .
        ?person info:age ?age .
    }
    

      将上述查询语句保存为文件q-opt2.rq,放到doc/Tutorial目录下。在终端执行命令:

    sparql --data=vc-db-2.rdf --query=q-opt2.rq
    

      返回查询结果如下图。
    在这里插入图片描述
      Filter关键词也可以在optional中使用,如下所示:

    PREFIX info:        <http://somewhere/peopleInfo#>
    PREFIX vcard:      <http://www.w3.org/2001/vcard-rdf/3.0#>
    
    SELECT ?name ?age
    WHERE
    {
        ?person vcard:FN  ?name .
        OPTIONAL { ?person info:age ?age . FILTER ( ?age > 24 ) }
    }
    

      上述查询将filter关键词放在optional的三元组中,因此filter只对该三元组的结果有效。将上述查询语句保存为文件q-opt3.rq,放到doc/Tutorial目录下。在终端执行命令:

    sparql --data=vc-db-2.rdf --query=q-opt3.rq
    

      返回查询结果如下图。
    在这里插入图片描述
      如果将filter放到外面,filter将对所有返回结果都有效,例如:

    PREFIX info:        <http://somewhere/peopleInfo#>
    PREFIX vcard:      <http://www.w3.org/2001/vcard-rdf/3.0#>
    
    SELECT ?name ?age
    WHERE
    {
        ?person vcard:FN  ?name .
        OPTIONAL { ?person info:age ?age . }
        FILTER ( !bound(?age) || ?age > 24 )
    }
    

      Filter中的条件表示若实体存在age属性,则必须大于24,否则不返回。对于不存在age属性的实体,仍可以返回。这是因为!bound表示未绑定的意思,!bound(?age)意思是实体可以没有age属性。因此这个filter语句的含义是:保留age大于24的实体或者没有age属性的实体。将上述查询语句保存为文件q-opt4.rq,放到doc/Tutorial目录下。在终端执行命令:

    sparql --data=vc-db-2.rdf --query=q-opt4.rq
    

      返回查询结果如下图。
    在这里插入图片描述
      如果filter中没有!bound(?age),则只会返回一个结果,如下:
    在这里插入图片描述

    7 Alternatives in a Pattern

      有时我们需要联合多种条件进行查询,UNION关键词可以实现此目的。UNION用于联合多个查询三元组,只要实体满足其中一个三元组即可返回。本节使用的数据内容如下:

    @prefix foaf: <http://xmlns.com/foaf/0.1/> .
    @prefix vcard: <http://www.w3.org/2001/vcard-rdf/3.0#> .
    
    _:a foaf:name   "Matt Jones" .
    _:b foaf:name   "Sarah Jones" .
    _:c vcard:FN    "Becky Smith" .
    _:d vcard:FN    "John Smith" .
    

      将上述内容保存为文件vc-db-3.ttl,放到doc/Tutorial目录下。查询语句如下:

    PREFIX foaf: <http://xmlns.com/foaf/0.1/>
    PREFIX vCard: <http://www.w3.org/2001/vcard-rdf/3.0#>
    
    SELECT ?name
    WHERE
    {
       { [] foaf:name ?name } UNION { [] vCard:FN ?name }
    }
    

      将上述查询语句保存为文件q-union1.rq,放到doc/Tutorial目录下。在终端执行命令:

    sparql --data=vc-db-3.ttl --query=q-union1.rq
    

      返回查询结果如下图。
    在这里插入图片描述
      也可以使用filter关键词实现同样的功能,查询语言如下:

    PREFIX foaf: <http://xmlns.com/foaf/0.1/>
    PREFIX vCard: <http://www.w3.org/2001/vcard-rdf/3.0#>
    
    SELECT ?name
    WHERE
    {
      [] ?p ?name
      FILTER ( ?p = foaf:name || ?p = vCard:FN )
    }
    

      这种方式效率可能没有前一种快,这里是先查询出所有的实体,然后在进行过滤。将上述查询语句保存为文件q-union-1alt.rq,放到doc/Tutorial目录下。在终端执行命令:

    sparql --data=vc-db-3.ttl --query=q-union-1alt.rq
    

      返回查询结果和上一个相同。

    8 Datasets

      有时候一个graph中含有多个graph,例如下面的default graph中含有ds-ng-1.ttl和ds-ng-2.ttl。

    @prefix dc: <http://purl.org/dc/elements/1.1/> .
    @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
    
    <ds-ng-1.ttl> dc:date "2005-07-14T03:18:56+0100"^^xsd:dateTime .
    <ds-ng-2.ttl> dc:date "2005-09-22T05:53:05+0100"^^xsd:dateTime .
    

      ds-ng-1.ttl是一个named graph,其内容如下:

    @prefix dc: <http://purl.org/dc/elements/1.1/> .
    
    [] dc:title "Harry Potter and the Philospher's Stone" .
    [] dc:title "Harry Potter and the Chamber of Secrets" .
    

      ds-ng-2.ttl是一个named graph,其内容如下:

    @prefix dc: <http://purl.org/dc/elements/1.1/> .
    
    [] dc:title "Harry Potter and the Sorcerer's Stone" .
    [] dc:title "Harry Potter and the Chamber of Secrets" .
    

      返回default graph中的所有三元组,尽管default graph中引用了其他的named graph,这些named graph中的三元组是不会返回的。查询语句如下:

    PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
    PREFIX dc: <http://purl.org/dc/elements/1.1/>
    PREFIX : <.>
    
    SELECT *
    { ?s ?p ?o }
    

      其中的“PREFIX : <.>” 仅是为了简化输出格式。将上述查询语句保存为文件q-ds-1.rq,放到doc/Tutorial目录下。在终端执行命令:

    sparql --data=ds-dft.ttl --query=q-ds-1.rq
    

      返回查询结果如下。
    在这里插入图片描述
      下面的查询语句将返回引用的named graph内容。查询语句如下所示:

    PREFIX  xsd:    <http://www.w3.org/2001/XMLSchema#>
    PREFIX  dc:     <http://purl.org/dc/elements/1.1/>
    PREFIX  :       <.>
    
    SELECT *
    {
        { ?s ?p ?o } UNION { GRAPH ?g { ?s ?p ?o } }
    }
    

      GRPHA关键词表示变量g是一个named graph。将上述查询语句保存为文件q-ds-2.rq,放到doc/Tutorial目录下。在终端执行命令:

    sparql --data=ds-dft.ttl --query=q-ds-2.rq --graph ds-dft.ttl --namedgraph ds-ng-1.ttl --namedgraph ds-ng-2.ttl
    

      返回查询结果如下。
    在这里插入图片描述
      也可以指定查询某个named graph,如下查询语句指定查询ds-ng-2.ttl。

    PREFIX dc: <http://purl.org/dc/elements/1.1/>
    PREFIX : <.>
    
    SELECT ?title
    {
      GRAPH :ds-ng-2.ttl
        { ?b dc:title ?title }
    }
    

      将上述查询语句保存为文件q-ds-3.rq,放到doc/Tutorial目录下。在终端执行命令:

    sparql --data=ds-dft.ttl --query=q-ds-3.rq --graph ds-dft.ttl --namedgraph ds-ng-1.ttl --namedgraph ds-ng-2.ttl
    

      返回查询结果如下。
    在这里插入图片描述
      Named graph也可以作为一个变量,使用条件查询来选择named graph。查询语句如下:

    PREFIX  xsd:    <http://www.w3.org/2001/XMLSchema#>
    PREFIX  dc:     <http://purl.org/dc/elements/1.1/>
    PREFIX  :       <.>
    
    SELECT ?date ?title
    {
      ?g dc:date ?date . FILTER (?date > "2005-08-01T00:00:00Z"^^xsd:dateTime )
      GRAPH ?g
          { ?b dc:title ?title }
    }
    

      Filter关键词筛选变量g,然后将g作为named graph。将上述查询语句保存为文件q-ds-4.rq,放到doc/Tutorial目录下。在终端执行命令:

    sparql --data=ds-dft.ttl --query=q-ds-4.rq --graph ds-dft.ttl --namedgraph ds-ng-1.ttl --namedgraph ds-ng-2.ttl
    

      返回查询结果如下。
    在这里插入图片描述

    展开全文
  • Sparql Examples

    2020-12-09 09:39:38
    <div><p>Hi an eta on sparql examples ?</p><p>该提问来源于开源项目:aws-samples/amazon-neptune-samples</p></div>
  • Learning SparQL

    2015-11-28 08:46:26
    Get hands-on experience with SPARQL, the RDF query language that's become a key component of the semantic web. With this concise book, you will learn how to use the latest version of this W3C standard...
  • SPARQL生成 该项目包含基于Apache Jena的SPARQL-Generate和STTL(也称为SPARQL-Template)实现的源。
  • SparQL使用

    2020-10-11 19:23:25
    一、SPARQL SPARQLSPARQL Protocol and RDF Query Language的递归缩写,专门用于访问和操作RDF数据,是语义网的核心技术之一。W3C的RDF数据存取小组(RDF Data Access Working Group, RDAWG)对其进行了标准化。...

    一、SPARQL

    SPARQL即SPARQL Protocol and RDF Query Language的递归缩写,专门用于访问和操作RDF数据,是语义网的核心技术之一。W3C的RDF数据存取小组(RDF Data Access Working Group, RDAWG)对其进行了标准化。在2008年,SPARQL 1.0成为W3C官方所推荐的标准。2013年发布了SPARQL 1.1。相对第一个版本,其支持RDF图的更新,提供更强大的查询,比如:子查询、聚合操作(像我们常用的count)等等。

    从SPARQL的全称我们可以知道,其由两个部分组成:协议和查询语言。

    1. 查询语言很好理解,就像SQL用于查询关系数据库中的数据,XQuery用于查询XML数据,SPARQL用于查询RDF数据。
    2. 协议是指我们可以通过HTTP协议在客户端和SPARQL服务器(SPARQL endpoint)之间传输查询和结果,这也是和其他查询语言最大的区别。

    一个SPARQL查询本质上是一个带有变量的RDF图,以我们之前提到的罗纳尔多RDF数据为例:

    <http://www.kg.com/person/1> <http://www.kg.com/ontology/chineseName> "罗纳尔多·路易斯·纳萨里奥·德·利马"^^string.

    我们把属性值用变量代替(SPARQL中,用问号加变量名的方式来表示一个变量。),即:

    <http://www.kg.com/person/1> <http://www.kg.com/ontology/chineseName> ?x.

     

    SPARQL查询是基于图匹配的思想。我们把上述的查询与RDF图进行匹配,找到符合该匹配模式的所有子图,最后得到变量的值。就上面这个例子而言,在RDF图中找到匹配的子图后,将”罗纳尔多·路易斯·纳萨里奥·德·利马”和“?x”绑定,我们就得到最后的结果。简而言之,SPARQL查询分为三个步骤:

    1. 构建查询图模式,表现形式就是带有变量的RDF。
    2. 匹配,匹配到符合指定图模式的子图。
    3. 绑定,将结果绑定到查询图模式对应的变量上。

    二、例子

    以实践篇的RDF电影数据为例,我们介绍如何利用SPARQL查询:

    1. 所有的RDF三元组。
    2. 周星驰出演了哪些电影?
    3. 英雄这部电影有哪些演员参演?
    4. 巩俐参演的评分大于7的电影有哪些?

    如何查询所有数据?参照我们在第一个部分介绍的查询过程,查询所有数据即我们没有任何已知值,SPO三元组每个都是未知变量。对应的SPARQL查询语言为:

    PREFIX : <http://www.kgdemo.com#>
    PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
    PREFIX owl: <http://www.w3.org/2002/07/owl#>
    PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
    PREFIX vocab: <http://localhost:2020/resource/vocab/>
    PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
    PREFIX map: <http://localhost:2020/resource/#>
    PREFIX db: <http://localhost:2020/resource/>
    
    SELECT * WHERE {
      ?s ?p ?o
    }

     

    SPARQL的部分关键词:

    • SELECT, 指定我们要查询的变量。在这里我们查询所有的变量,用*代替。
    • WHERE,指定我们要查询的图模式。含义上和SQL的WHERE没有区别。
    • FROM,指定查询的RDF数据集。我们这里只有一个图,因此省去了FROM关键词。
    • PREFIX,用于IRI的缩写。

    下面是该语句的部分查询结果:

    s                    p             o
    
    db:genre/12 [http]  :genreName  "冒险"
    db:genre/12 [http]  rdf:type    :Genre
    db:genre/14 [http]  :genreName  "奇幻"
    db:genre/14 [http]  rdf:type    :Genre
    db:genre/16 [http]  :genreName  "动画"
    db:genre/16 [http]  rdf:type    :Genre
    db:genre/18 [http]  :genreName  "剧情"
    db:genre/18 [http]  rdf:type    :Genre
    db:genre/27 [http]  :genreName  "恐怖"
    db:genre/27 [http]  rdf:type    :Genre
    

     

    “周星驰出演了哪些电影”:

    PREFIX : <http://www.kgdemo.com#>
    PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
    PREFIX owl: <http://www.w3.org/2002/07/owl#>
    PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
    PREFIX vocab: <http://localhost:2020/resource/vocab/>
    PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
    PREFIX map: <http://localhost:2020/resource/#>
    PREFIX db: <http://localhost:2020/resource/>
    
    SELECT ?n WHERE {
      ?s rdf:type :Person.
      ?s :personName '周星驰'.
      ?s :hasActedIn ?o.
      ?o :movieTitle ?n
    }

     

    n
    
    "功夫"
    "琉璃樽"
    "英雄本色"
    "少林足球"
    "西游记第壹佰零壹回之月光宝盒"
    "长江七号"
    "西游记大结局之仙履奇缘"
    "建国大业"
    "审死官"
    "龙在天涯"
    "大内密探零零发"

    就我们这个例子而言,可以不要“?s rdf:type :Person”,这里只是让查询图更具体(在拥有复杂关系的RDF图中,可能会存在不同的类拥有相同的属性名。比如,猫和狗名字的属性名都是”name”,我们想查询一只叫汤姆的猫;如果不指定类型,返回结果可能也包含一只叫汤姆的狗)。图模式中,每个RDF用英文句号进行分割。

    “英雄这部电影有哪些演员参演”:

    PREFIX : <http://www.kgdemo.com#>
    PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
    PREFIX owl: <http://www.w3.org/2002/07/owl#>
    PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
    PREFIX vocab: <http://localhost:2020/resource/vocab/>
    PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
    PREFIX map: <http://localhost:2020/resource/#>
    PREFIX db: <http://localhost:2020/resource/>
    
    SELECT ?n WHERE {
      ?s rdf:type :Movie.
      ?s :movieTitle '英雄'.
      ?a :hasActedIn ?s.
      ?a :personName ?n
    }

    结果:

    n
    
    "李连杰"
    "梁朝伟"
    "张曼玉"
    "章子怡"
    "甄子丹"

    “巩俐参演的评分大于7的电影有哪些”:

    PREFIX : <http://www.kgdemo.com#>
    PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
    PREFIX owl: <http://www.w3.org/2002/07/owl#>
    PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
    PREFIX vocab: <http://localhost:2020/resource/vocab/>
    PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
    PREFIX map: <http://localhost:2020/resource/#>
    PREFIX db: <http://localhost:2020/resource/>
    
    SELECT ?n WHERE {
      ?s rdf:type :Person.
      ?s :personName '巩俐'.
      ?s :hasActedIn ?o.
      ?o :movieTitle ?n.
      ?o :movieRating ?r.
    FILTER (?r >= 7)
    }

    结果:

    n
    
    "2046"
    "Memoirs of a Geisha"
    "荆轲刺秦王"
    "大红灯笼高高挂"
    "霸王别姬"
    "活着"
    "唐伯虎点秋香"
    "秋菊打官司"
    "菊豆"
    "Hong gao liang"
    "画魂"
    "风月"
    "Piao Liang Ma Ma"
    "The Hand"

    这里我们用到了FILTER关键词,可以对变量取值进行约束。

    SPARQL更详细的语法和功能这里就不再多做介绍。读者可以参考W3C的文档或者SPARQL查询的例子,也有专门的书来讲解SPARQL 1.1(Learning SPARQL: Querying and Updating with SPARQL 1.1)

    另外多提一点,关于知识图谱,有一个非常重要的概念,即开放世界假定(Open-world assumption,OWA)。这个假定的意思是当前没有陈述的事情是未知的,或者说知识图谱没有包含的信息是未知的。怎么理解?首先我们要承认知识图谱无法包含所有完整的信息。以我们这个电影数据的例子而言,很明显,它的数据十分残缺。即使我们拥有一个十分完整的电影知识图谱,包含了当下所有的电影、演员等信息,在现实世界中,信息也是动态变化和增长的。即,我们要承认知识图谱的信息本身就是残缺的。有了这个前提,我们来思考例子中的第二个SPARQL语句:

    周星驰出演了上述查询结果中的电影。基于我们构建的电影知识图谱,提问:周星驰出演了《卧虎藏龙》吗?根据OWA,我们得到的答案是“不知道”,相反,如果是封闭世界假定(Closed-world assumption),我们得到的答案是“没有出演”。

    我们在设计本体和开发相关应用的时候需要考虑开放世界假定。举个简单的例子,基于知识图谱的问答系统,用户提问“周星驰出演了《卧虎藏龙》吗?”,合适的回答是“不知道”而不是“没有出演”。直觉上这和一个人向另一个人提这个问题一样,如果我们知道问题答案,我们会给出肯定的回答,不知道的话,我们往往倾向于回复“我不知道”,“我不太清楚”,“我查查看”,而不是信誓旦旦地回答“没有出演”。毕竟,大多数人都有“自知之明”,知道自己总有不了解的东西。从这个角度上说,人和知识图谱类似,我们都存在于OWA的世界中。

    三、总结

    本文主要介绍了SPARQL及其基本用法,希望能让读者对SPARQL有个初步的认识。下一篇文章是实践篇,介绍如何利用D2RQ创建SPARQL endpoint并在我们的数据上进行相关查询。

    参考资料

    1. Learn SPARQL
    2. SPARQL By Example
    3. SPARQL Query Language for RDF
    4. OWA

     

    原文链接:https://blog.csdn.net/u011801161/article/details/78994262

    展开全文
  • SPARQL客户端,可以更轻松地处理SPARQL查询和图形存储请求。 用于和。 用于管理命名图。 入门示例 TL; DR; 该包将导出一个StreamClient类,该类在端点上运行SPARQL查询。 const SparqlClient = require ( 'sparql-...
  • If my only Comunica source is this GraphDB SPARQL endpoint, I get the expected result. When I add another source and execute the query, it returns a 400 ERROR: <code>Could not retrieve ...
  • SPARQL Update

    2020-12-09 09:17:42
    <div><h4>Issue type: ...In the future, we should also add support for <a href="https://www.w3.org/TR/sparql11-update/">update queries</a>.</p><p>该提问来源于开源项目:comunica/comunica</p></div>
  • the user <code>demo</code> with password <code>demo</code> is set to <code>sql/odbc and webDAV</code> roles are set to <code>sparql_load_service_data</code> and <code>sparql_update</code>. default ...
  • sparql2storymap 使用SPARQL创建一个 。 用法 有关示例,请参见和 。 包括要求: <link rel="stylesheet" href="https://cdn.knightlab.com/libs/storymapjs/latest/css/storymap.css"> [removed][removed...
  • 使用JavaScript进行SPARQL处理的样本 是一组示例程序,由的Furusaki准备,学习使用SPARQL进行毕业研究的程序开发技能。 我们计划在将来逐步增加它。 simpleSPARQL 最基本的程序。首先,请参考这里 SPARQL-JS-样本 在...
  • SPARQL.js –用于JavaScript的SPARQL 1.1解析器 允许查询数据源。 SPARQL.js将SPARQL转换为JSON并返回,因此您可以在JavaScript应用程序中解析和构建SPARQL查询。 它还在sparqlStar选项下包含对扩展的sparqlStar 。...
  • SPARQLSPARQL代数转换器 公开了2个组件:平移函数和Algebra对象,其中包含所有可能发生的输出类型。 请注意,这仍在进行中,因此命名约定可能会更改。 还支持“非代数”实体,例如ASK,FROM等,以确保输出包含...
  • SPARQL求助

    2020-03-13 19:37:58
    最近在学利用jena调用sparql,遇到了问题:我想把sparql语句中的"软件工程"替换成我声明的字符串"专业",哪位大神会,求解,万分感谢!
  • SPARQL实验室查询 ZBW和相关数据集的SPARQL查询存储库 已针对Fuseki上运行的ZBW Labs SPARQL端点测试了此存储库中的查询。 可以通过下面的链接查看,编辑和执行它们。 默认端点是...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,937
精华内容 774
关键字:

sparql