每当我开始使用SQL时,我倾向于向数据库发送一些探索性语句,以了解可用的数据和数据的形式。
例如:
show tables
describe table
select * from table
有没有人能帮我理解如何使用SPARQL端点完成RDF数据存储的类似探索?
首先,显而易见的是要查看数据中存在哪些类和属性。
以下是查看正在使用哪些类的方法:
SELECT DISTINCT ?class
WHERE {
?s a ?class .
}
LIMIT 25
OFFSET 0
(LIMIT
和OFFSET
用于分页。如果您要通过互联网发送查询,请务必了解这些内容。在其他示例中,我将省略它们。)
a
是一种特殊的SPARQL(以及Notation3/Turtle)语法,用于表示rdf:type
谓词 - 它将单个实例链接到owl:Class
/rdfs:Class
类型(在SQL RDBMSes中大致相当于表格)。
其次,您需要查看属性。您可以通过使用搜索到的类或仅查找属性来执行此操作。让我们从存储中获取所有属性:
SELECT DISTINCT ?property
WHERE {
?s ?property ?o .
}
这将获取所有属性,但您可能对此不感兴趣。这相当于SQL中所有行列的列表,但没有按表进行分组。
更有用的是查看声明特定类的实例正在使用哪些属性:
SELECT DISTINCT ?property
WHERE {
?s a <http://xmlns.com/foaf/0.1/Person>;
?property ?o .
}
这将为您获取满足第一个三元组条件的任何实例使用的属性 - 即具有 rdf:type
为 http://xmlns.com/foaf/0.1/Person
的实例。
记住,因为 rdf:Resource 可以具有多个 rdf:type 属性(也就是类),并且因为 RDF 的数据模型是添加性的,所以你不会遇到钻石问题。类型只是另一个属性 - 它仅仅是一种有用的社会协议,表示某些事物是人或狗或基因或足球队。这并不意味着数据存储将包含通常与该类型相关联的属性。类型并不能保证资源可能具有哪些属性。isLiteral
来过滤出仅为字面值的属性。SELECT DISTINCT ?property
WHERE {
?s a <http://xmlns.com/foaf/0.1/Person>;
?property ?o .
FILTER isLiteral(?o)
}
我们在这里只获取其对象为字面值的属性 - 字符串、日期时间、布尔值或其他XSD数据类型之一。
但是那些非字面量对象怎么办?考虑一下这个非常简单的伪Java类定义作为比喻:
public class Person {
int age;
Person marriedTo;
}
使用上述查询,如果年龄属性已绑定,我们将获取表示年龄的字面量。但marriedTo不是一个原始值(即在RDF术语中的字面量)-它是对另一个对象的引用-在RDF / OWL术语中,这是一个对象属性。但我们不知道这些属性(谓词)所引用的对象类型是什么。此查询将返回伴随类型的属性(其?o
值是成员的类)。
SELECT DISTINCT ?property, ?class
WHERE {
?s a <http://xmlns.com/foaf/0.1/Person>;
?property ?o .
?o a ?class .
FILTER(!isLiteral(?o))
}
这应该足以让你在特定的数据集中找到方向。当然,我还建议你提取一些单独的资源并检查它们。你可以使用DESCRIBE查询来做到这一点:
DESCRIBE <http://example.org/resource>
有一些SPARQL工具,例如SNORQL,可以让您在浏览器中执行此操作。我链接的SNORQL实例具有一个用于探索可能命名图形的示例查询,这里没有涵盖。
如果您不熟悉SPARQL,老实说,卡住时最好的资源就是规范。它是W3C规范,但相当不错(他们构建了一个不错的测试套件,因此您可以实际上看到实现是否正确完成),如果您可以解决复杂的语言问题,它非常有帮助。
我发现以下探索性查询集合很有用:
查看类:
select distinct ?type ?label
where {
?s a ?type .
OPTIONAL { ?type rdfs:label ?label }
}
查看属性:
select distinct ?objprop ?label
where {
?objprop a owl:ObjectProperty .
OPTIONAL { ?objprop rdfs:label ?label }
}
查看数据属性:
select distinct ?dataprop ?label
where {
?dataprop a owl:DatatypeProperty .
OPTIONAL { ?dataprop rdfs:label ?label }
}
查看实际使用的属性:
select distinct ?p ?label
where {
?s ?p ?o .
OPTIONAL { ?p rdfs:label ?label }
}
查看已声明的实体:
select distinct ?entity ?elabel ?type ?tlabel
where {
?entity a ?type .
OPTIONAL { ?entity rdfs:label ?elabel } .
OPTIONAL { ?type rdfs:label ?tlabel }
}
看到不同类型的图表使用:
select distinct ?g where {
graph ?g {
?s ?p ?o
}
}
特别是在处理大型数据集时,区分模式和噪声并理解哪些结构被广泛使用,哪些很少使用是非常重要的。我使用聚合查询来计算主要类别、谓词等,而不是使用SELECT DISTINCT
。例如,以下是如何查看数据集中最重要的谓词:
SELECT ?pred (COUNT(*) as ?triples)
WHERE {
?s ?pred ?o .
}
GROUP BY ?pred
ORDER BY DESC(?triples)
LIMIT 100
我通常会首先列出代码库中的图表及其大小,然后查看感兴趣的图表中的类别(同样是计数),接着是我感兴趣的类别的谓词等。
当然,如果适当的话,可以结合和限制这些选择器。要查看定义为foaf:Person
类型实例的谓词,并按图表进行分解,你可以使用以下内容:
SELECT ?g ?pred (COUNT(*) as ?triples)
WHERE {
GRAPH ?g {
?s a foaf:Person .
?s ?pred ?o .
}
GROUP BY ?g ?pred
ORDER BY ?g DESC(?triples)
SELECT DISTINCT * WHERE {
?s ?p ?o
}
LIMIT 10