52

每当我开始使用 SQL 时,我倾向于在数据库中抛出一些探索性语句,以了解可用的内容以及数据的形式。

例如

show tables

describe table

select * from table

谁能帮助我了解使用 SPARQL 端点完成对 RDF 数据存储的类似探索的方法?

4

5 回答 5

95

嗯,显而易见的第一个开始是查看数据中存在的类和属性。

以下是如何查看正在使用的类:

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

LIMIT并且OFFSET在那里用于分页。值得习惯这些,特别是如果您通过 Internet 发送查询。我将在其他示例中省略它们。)

a是一种特殊的 SPARQL(和Notation3 / Turtle)语法来表示rdf:type谓词 - 它将单个实例链接到owl:Class/rdfs:Class类型(大致相当于 SQL RDBMS 中的表)。

其次,您要查看属性。您可以通过使用已搜索的类或仅查找属性来执行此操作。让我们从商店中取出所有属性:

SELECT DISTINCT ?property
WHERE {
  ?s ?property ?o .
}

这将获取您可能不感兴趣的所有属性。这相当于 SQL 中所有行列的列表,但没有按表进行任何分组。

更有用的是查看声明特定类的实例正在使用哪些属性:

SELECT DISTINCT ?property
WHERE {
  ?s a <http://xmlns.com/foaf/0.1/Person>;
     ?property ?o .
}

这将使您恢复在满足第一个三元组的任何实例上使用的属性 - 即具有rdf:typeof http://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 规范,但非常好(他们构建了一个不错的测试套件,因此您可以实际查看实现是否正确完成),如果您能克服复杂的语言,这将非常有帮助。

于 2010-05-30T23:16:15.710 回答
9

我发现以下一组探索性查询很有用:

看课:

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 
    } 
}
于 2016-04-20T11:57:07.693 回答
3
SELECT DISTINCT * WHERE {
  ?s ?p ?o
}
LIMIT 10
于 2010-07-27T11:54:26.833 回答
2

我经常参考来自 voiD 项目的查询列表。它们主要具有统计性​​质,但不仅如此。从某些语句中删除 COUNT 以获得实际值应该不难。

于 2010-05-31T15:21:01.680 回答
1

尤其是对于大型数据集,重要的是要区分模式和噪声,并了解哪些结构被大量使用,哪些结构很少。而不是SELECT DISTINCT,我使用聚合查询来计算主要类、谓词等。例如,以下是如何查看数据集中最重要的谓词:

SELECT ?pred (COUNT(*) as ?triples)
WHERE {
    ?s ?pred ?o .
}
GROUP BY ?pred
ORDER BY DESC(?triples)
LIMIT 100

我通常首先列出存储库中的及其大小,然后查看感兴趣的图中的(再次使用计数) ,然后查看我感兴趣的类的谓词等。

当然,如果合适的话,这些选择器可以组合和限制。要查看为 type 的实例定义了哪些谓词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)

这将按频率降序列出每个图表及其中的谓词。

于 2021-06-15T09:10:56.013 回答