探索性SPARQL查询?

52

每当我开始使用SQL时,我倾向于向数据库发送一些探索性语句,以了解可用的数据和数据的形式。

例如:

show tables

describe table

select * from table

有没有人能帮我理解如何使用SPARQL端点完成RDF数据存储的类似探索?

5个回答

97

首先,显而易见的是要查看数据中存在哪些类和属性。

以下是查看正在使用哪些类的方法:

SELECT DISTINCT ?class
WHERE {
  ?s a ?class .
}
LIMIT 25
OFFSET 0

(LIMITOFFSET用于分页。如果您要通过互联网发送查询,请务必了解这些内容。在其他示例中,我将省略它们。)

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:typehttp://xmlns.com/foaf/0.1/Person 的实例。

记住,因为 rdf:Resource 可以具有多个 rdf:type 属性(也就是类),并且因为 RDF 的数据模型是添加性的,所以你不会遇到钻石问题。类型只是另一个属性 - 它仅仅是一种有用的社会协议,表示某些事物是人或狗或基因或足球队。这并不意味着数据存储将包含通常与该类型相关联的属性。类型并不能保证资源可能具有哪些属性。
您需要熟悉数据模型和 SPARQL 的 UNION 和 OPTIONAL 语法的使用。rdf:type 到 SQL 表的大致映射只是粗略的。
您可能想知道属性指向的实体类型。首先,您可能想了解数据类型属性 - 相当于文本或原始数据类型。您知道,字符串,整数等等。RDF 将所有这些字面值定义为从字符串继承的。我们可以使用 SPARQL 过滤方法 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规范,但相当不错(他们构建了一个不错的测试套件,因此您可以实际上看到实现是否正确完成),如果您可以解决复杂的语言问题,它非常有帮助。


1
我知道在SO上发布简单的“谢谢!”信息是不被允许的,但你刚刚帮助了一个SPARQL新手,所以:“谢谢!”。 - Ben Hillier

10

我发现以下探索性查询集合很有用:

查看类:

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

3

特别是在处理大型数据集时,区分模式和噪声并理解哪些结构被广泛使用,哪些很少使用是非常重要的。我使用聚合查询来计算主要类别、谓词等,而不是使用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)

这将按频率从高到低的顺序列出每个谓词所在的图表。

3
SELECT DISTINCT * WHERE {
  ?s ?p ?o
}
LIMIT 10

这将返回类型为(主题,属性,对象)的元组。如果您不指定限制,则会返回所有数据,这可能是相当多的。 - thmmy95

2
我经常参考这个 voiD项目的查询列表。它们主要是统计性质的,但不仅限于此。从某些语句中删除COUNT应该不难得到实际值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接