数据集
本节介绍 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
下一篇:结果
一、问题描述
二、算法思想
###如果的投入
能缩进两个汉字
能缩进一个汉字,可叠加
能缩进半个汉字,可叠加
能缩进四分之一,可叠加
三、代码
在这里插入代码片