SPARQL 教程七

数据集

本节介绍 RDF 数据集–RDF 数据集是 SPARQL 查询的查询单元。它由一个默认图和若干命名图组成。

查询数据集

  图匹配操作(基本模式、OPTIONAL 和 UNION)在一个 RDF 图上运行。 该图一开始是数据集的默认图,但可以通过 GRAPH 关键字进行更改。

GRAPH uri { ... pattern ... }

GRAPH var { ... pattern ... }

  在SPARQL查询中使用 GRAPH 子句时,如果提供了一个URI,那么查询将在数据集中寻找与该URI对应的图,并在该图上执行模式匹配;如果找不到对应的图,那么整个 GRAPH 子句将无法匹配。

示例数据

  一个RDF数据集可以有不同的设置。其中两种常见的设置是:将默认图设置为所有命名图的并集(RDF合并),或者将默认图设置为命名图的清单(包括命名图的来源、读取时间等)。在第一种设置中,所有命名图的三元组会合并在一起,形成一个默认图。这样,查询将同时考虑所有命名图中的三元组。第二种设置中的默认图并不包含实际的三元组数据,而是用来存储命名图的附加信息,这可以是关于命名图的元数据,比如它们的来源和读取时间等。这种设置有助于更好地组织和管理RDF数据集中的图。在RDF数据集中,没有限制。一个图可以以不同的名称多次包含,也可以一些图与其他图共享三元组。

默认图 (ds-dft.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):

@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):

@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" .

  也就是说,我们有两个描述一些书的小图,我们还有一个默认图,记录这些图最后一次阅读的时间。

  可以使用命令行应用程序运行查询(这将是一行):

java -cp ... arq.sparql
    --graph ds-dft.ttl --namedgraph ds-ng-1.ttl --namedgraph ds-ng-2.ttl
    --query query file

  数据集不必只在查询期间创建。 数据集可以创建并存储在数据库中,这在聚合应用程序中更为常见。

访问数据集

  第一个示例只访问默认图形(q-ds-1.rq):

PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX : <.>

SELECT *
{ ?s ?p ?o }

(PREFIX : <.>"只是帮助格式化输出结果)

----------------------------------------------------------------------
| s            | p       | o                                         |
======================================================================
| :ds-ng-2.ttl | dc:date | "2005-09-22T05:53:05+01:00"^^xsd:dateTime |
| :ds-ng-1.ttl | dc:date | "2005-07-14T03:18:56+01:00"^^xsd:dateTime |
----------------------------------------------------------------------

  这只是默认图–命名图中没有任何内容,因为除非通过 GRAPH 明确指出,否则不会对它们进行查询。

Java 代码如下:

import org.apache.jena.query.Query;
import org.apache.jena.query.QueryExecution;
import org.apache.jena.query.QueryExecutionFactory;
import org.apache.jena.query.QueryFactory;
import org.apache.jena.query.QuerySolution;
import org.apache.jena.query.ResultSet;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.riot.Lang;
import org.apache.jena.riot.RDFDataMgr;

public class Datasets01 {
    static final String inputFileName  = "java01/src/main/java/come/jena/rdf/ds-dft.ttl";
    public static void main(String[] args) {
        // Load RDF data into a model
        Model model = ModelFactory.createDefaultModel();
        RDFDataMgr.read(model, inputFileName, Lang.TURTLE);
        String queryString =  "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>\n" +
                "PREFIX dc: <http://purl.org/dc/elements/1.1/>\n" +
                "PREFIX : <.>\n" +
                "SELECT *\n     { ?s ?p ?o }\n";
        Query query = QueryFactory.create(queryString);
        try (QueryExecution qexec = QueryExecutionFactory.create(query, model)) {
            ResultSet results = qexec.execSelect();
            // Process the query results
            while (results.hasNext()) {
                QuerySolution soln = results.nextSolution();
                String s1 = soln.get("s").toString();
                System.out.print("s: " + s1.substring(s1.lastIndexOf("/")+1));

                String p = soln.get("p").toString();
                if (prefixMap.containsKey(p)) {
                    p = prefixMap.get(p);
                }

                System.out.print("     p: " + p);
                System.out.println("\t o: " + soln.get("o").toString().replace("http://www.w3.org/2001/XMLSchema#", "xsd:"));
            }
        }
        catch (Exception e){
            e.printStackTrace();
        }
    }
}

运行结果:

在这里插入图片描述

  我们可以通过查询默认图和命名图(q-ds-2.rq)来查询所有三元组:

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 } }
}

得到以下结果:

---------------------------------------------------------------------------------------
| s            | p        | o                                          | g            |
=======================================================================================
| :ds-ng-2.ttl | dc:date  | "2005-09-22T05:53:05+01:00"^^xsd:dateTime  |              |
| :ds-ng-1.ttl | dc:date  | "2005-07-14T03:18:56+01:00"^^xsd:dateTime  |              |
| _:b0         | dc:title | "Harry Potter and the Sorcerer's Stone"    | :ds-ng-2.ttl |
| _:b1         | dc:title | "Harry Potter and the Chamber of Secrets"  | :ds-ng-2.ttl |
| _:b2         | dc:title | "Harry Potter and the Chamber of Secrets"  | :ds-ng-1.ttl |
| _:b3         | dc:title | "Harry Potter and the Philospher's Stone"  | :ds-ng-1.ttl |
---------------------------------------------------------------------------------------

Java 代码:

package come.xbmu.sparql;
import org.apache.jena.query.Query;
import org.apache.jena.query.QueryExecution;
import org.apache.jena.query.QueryExecutionFactory;
import org.apache.jena.query.QueryFactory;
import org.apache.jena.query.QuerySolution;
import org.apache.jena.query.ResultSet;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.riot.Lang;
import org.apache.jena.riot.RDFDataMgr;

public class Datasets01 {
    static final String inputFileName  = "java01/src/main/java/come/xbmu/jena/rdf/ds-dft.ttl";
    static final String inputFileName1  = "java01/src/main/java/come/xbmu/jena/rdf/ds-ng-1.ttl";
    static final String inputFileName2  = "java01/src/main/java/come/xbmu/jena/rdf/ds-ng-2.ttl";
    public static void main(String[] args) {
        // Load RDF data into a model
        Model model = ModelFactory.createDefaultModel();
        RDFDataMgr.read(model, inputFileName, Lang.TURTLE);
        RDFDataMgr.read(model, inputFileName1, Lang.TURTLE);
        RDFDataMgr.read(model, inputFileName2, Lang.TURTLE);
        String queryString = "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>\n" +
                "PREFIX dc: <http://purl.org/dc/elements/1.1/>\n" +
                "PREFIX : <.>\n" +
                "SELECT *\n" +
                "{ { ?s ?p ?o } UNION { GRAPH ?g { ?s ?p ?o } } }";
        Query query = QueryFactory.create(queryString);
        try (QueryExecution qexec = QueryExecutionFactory.create(query, model)) {
            ResultSet results = qexec.execSelect();
            // Process the query results
            while (results.hasNext()) {
                QuerySolution soln = results.nextSolution();
                String s1 = soln.get("s").toString();
                System.out.print("s: " + s1.substring(s1.lastIndexOf("/")+1));

                String p = soln.get("p").toString().replace("http://purl.org/dc/elements/1.1/","dc:");
                System.out.print("     p: " + p);
                System.out.println("\t o: " + soln.get("o").toString().replace("http://www.w3.org/2001/XMLSchema#", "xsd:"));
            }
        }
        catch (Exception e){1
            e.printStackTrace();
        }
    }
}

运行结果:

在这里插入图片描述

查询一个特定的图

  如果应用程序知道图的名称,就可以直接进行查询,例如查找给定图中的所有title 的值(q-ds-3.rq):

PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX : <.>

SELECT ?title
{
  GRAPH :ds-ng-2.ttl
    { ?b dc:title ?title }
}

结果如下:

---------------------------------------------
| title                                     |
=============================================
| "Harry Potter and the Sorcerer's Stone"   |
| "Harry Potter and the Chamber of Secrets" |
---------------------------------------------

从图中查找符合模式的数据

  要查询的图的名称可以通过查询本身来确定。无论变量是图模式的一部分还是 GRAPH 形式的一部分,其处理过程都是相同的。下面的查询(q-ds-4.rq)根据默认图中的信息,对用于选择命名图的变量设置了一个条件。

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 }
}

  在执行查询时,对于给定的示例数据集,查询结果是来自其中一个图(命名图)的 title 和那些日期晚于2005年8月1日的图。

-----------------------------------------------------------------------------------------
| date                                      | title                                     |
=========================================================================================
| "2005-09-22T05:53:05+01:00"^^xsd:dateTime | "Harry Potter and the Sorcerer's Stone"   |
| "2005-09-22T05:53:05+01:00"^^xsd:dateTime | "Harry Potter and the Chamber of Secrets" |
-----------------------------------------------------------------------------------------

描述 RDF 数据集 —— FROM 和 FROM NAMED 字句

  在执行SPARQL查询时,可以在构建查询执行对象时提供数据集,也可以在查询本身中描述数据集。当数据集的细节在命令行中指定时,会创建一个临时数据集,但应用程序也可以创建数据集,然后在多个查询中使用它们。

  第一种情况下,数据集信息可以在构建查询执行对象时直接传递,使得查询执行对象知道要查询的数据集。这些数据集可以是临时的,只在查询执行期间使用。第二种情况下,数据集信息可以在查询本身中通过 “FROM” 和 “FROM NAMED” 子句来描述。这允许在查询内部指定要使用的命名图和默认图。这样的设置允许应用程序创建自定义的数据集,并在多个查询中重复使用这些数据集。这对于频繁执行类似查询的应用程序非常有用。

  在查询中描述时,FROM 用于识别默认图表中的内容。在查询中可以有多个 “FROM” 子句,当有多个 “FROM” 子句时,查询引擎会将每个URL指定的文件的内容读取到默认图中。默认图的内容是这些被读取的文件内容的RDF合并,即将每个文件的内容合并到一个默认图中。这种合并方式形成了默认图,其中包含了所有被指定的URL的内容。

  不要被 FROM 子句中一个或多个 URL 描述的默认图表所迷惑。这是从哪里读取数据,而不是图表的名称。由于可以给出多个 FROM 子句,因此可以从多个地方读取数据,但这些地方都不会成为图表名称。

  FROM NAMED 用于识别已命名的图表。图形的名称为 url,数据从该位置读取。多个 FROM NAMED 子句会将多个图表添加到数据集中。

  例如,查找默认图和命名图中所有三元组的查询可以写成 (q-ds-5.rq):

PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX dc:  <http://purl.org/dc/elements/1.1/>
PREFIX :    <.>

SELECT *
FROM       <ds-dft.ttl>
FROM NAMED <ds-ng-1.ttl>
FROM NAMED <ds-ng-2.ttl>
{
   { ?s ?p ?o } UNION { GRAPH ?g { ?s ?p ?o } }
}

Jena 官方文档:https://jena.apache.org/tutorials/sparql_datasets.html

下一篇:结果

一、问题描述

二、算法思想

###如果的投入
  能缩进两个汉字
 能缩进一个汉字,可叠加
 能缩进半个汉字,可叠加
 能缩进四分之一,可叠加

三、代码

在这里插入代码片

四、题目链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值