XQuery/SPARQL 教程
emp-dept RDF 可以通过 XQuery 前端 使用 SPARQL 查询 存储,由 Talis 提供。该脚本支持 SPARQL 查询和浏览 RDF 图。
该接口扩展了查询,例如
select ?name ?job where { ?emp rdf:type f:emp. ?emp foaf:surname ?name. ?emp f:Job ?job. }
prefix foaf: <http://xmlns.com/foaf/0.1/> prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> prefix f: <http://www.cems.uwe.ac.uk/empdept/concept/> prefix xs: <http://www.w3.org/2001/XMLSchema#> select ?name ?job where { ?emp rdf:type f:emp. ?emp foaf:surname ?name. ?emp f:Job ?job. }
并将其发送到 Talis 服务,该服务以可运行的形式提供,您可以在 此处 运行。生成的 SPARQLQuery Results XML 会被转换为 HTML。
select ?emp where { ?emp rdf:type f:emp. }
select ?name where { ?emp rdf:type f:emp. ?emp foaf:surname ?name. } ORDER BY ?name
select ?name ?sal ?dno ?job where { ?emp rdf:type f:emp; foaf:surname ?name; f:Sal ?sal; f:Dept ?dept; f:Job ?job. ?dept f:DeptNo ?dno. }
请注意,; 代替 . 用于重复主体。
select ?ename where { ?emp rdf:type f:emp; foaf:surname ?ename. } ORDER BY ?ename LIMIT 5
select ?ename ?sal where { ?emp rdf:type f:emp; foaf:surname ?ename; f:Sal ?sal. } ORDER BY DESC(?sal) LIMIT 5
select ?dept where { ?dept rdf:type f:dept. }
select ?dept ?emp where { {?dept rdf:type f:dept } UNION {?emp rdf:type f:emp} }
如果 RDF 文字类型,例如 xs:integer,就像此生成的 RDF 一样,则以下查询将选择薪资大于 1000 的员工
select ?emp ?sal where { ?emp rdf:type f:emp; f:Sal ?sal. FILTER (?sal > 1000) }
如果 RDF 文字没有类型,则必须强制转换变量
select ?emp ?sal where { ?emp rdf:type f:emp; f:Sal ?sal. FILTER (xs:integer(?sal) > 1000) }
select ?emp ?loc where { ?emp rdf:type f:emp. ?emp f:Dept ?dept. ?dept f:Location ?loc. }
select ?ename ?mname where { ?emp rdf:type f:emp; f:Mgr ?mgr; foaf:surname ?ename. ?mgr foaf:surname ?mname. }
select ?ename ?mname where { ?emp rdf:type f:emp; foaf:surname ?ename. OPTIONAL {?emp f:Mgr ?mgr. ?mgr foaf:surname ?mname. } }
select ?ename where { ?emp rdf:type f:emp; foaf:surname ?ename. OPTIONAL {?emp f:Mgr ?mgr} FILTER (!bound(?mgr)) }
select distinct ?loc where { ?emp rdf:type f:emp. ?emp f:Dept ?dept. ?dept f:Location ?loc. }
select * where { ?emp rdf:type f:emp. ?emp f:Dept ?dept. ?dept f:Location ?loc. ?emp f:Job ?job. FILTER (?job = "ANALYST") }
select ?emp where { ?emp rdf:type f:emp; f:Job ?job. FILTER (?job = "ANALYST" || ?job = "MANAGER") }
select * where { ?emp rdf:type f:emp; f:Job ?job. FILTER (?job != "ANALYST" && ?job != "MANAGER") }
select * where { ?emp rdf:type f:emp. ?emp foaf:surname ?ename. FILTER (regex(?ename, "^S")) }
select * where { ?emp rdf:type f:emp. ?emp foaf:surname ?ename. FILTER (regex(?ename, "AR")) }
select * where { ?emp rdf:type f:emp. ?emp foaf:surname ?ename. FILTER (regex(?ename, "m.*r","i")) }
SPARQL 1.0 缺乏 min() 或 max(),虽然它们被添加到了某些实现中。以下方法,由 Dean Allemang 提供,可以用来实现。
select ?maxemp ?maxsal where { ?maxemp rdf:type f:emp. ?maxemp f:Sal ?maxsal. OPTIONAL { ?emp rdf:type f:emp. ?emp f:Sal ?sal. FILTER ( ?sal > ?maxsal) }. FILTER (!bound (?sal)) }
这是如何工作的?我们寻找 **最高** 员工的最高薪水。对于这样的员工,OPTIONAL 子句将不匹配,因为没有员工的薪水更高,因此 ?sal 将不会绑定。
在 SPARQL 1.1 中,允许使用 max() 和 min(),所以返回最高薪水的查询变为
select (max(?sal) as ?maxsal) where { ?maxemp rdf:type f:emp. ?maxemp f:Sal ?sal. }
select * where { ?emp1 f:Sal ?sal. ?emp2 f:Sal ?sal. FILTER (?emp1 != ?emp2) }
select ?dname where { ?emp rdf:type f:emp. ?emp f:Dept ?dept. ?emp foaf:surname "SMITH". ?dept f:Dname ?dname. }
select ?ename where { ?emp rdf:type f:emp. ?emp f:Dept ?dept. ?emp foaf:surname ?ename. ?dept f:Dname "Accounting". }
select ?ename ?hire where { ?emp rdf:type f:emp. ?emp f:HireDate ?hire. ?emp foaf:surname ?ename. FILTER (?hire > "2000-01-01"^^xs:date) }
请注意,需要对字面量进行类型化才能使比较工作正常。
select ?name ?edname ?mdname { ?emp rdf:type f:emp; foaf:surname ?name; f:Dept ?dept; f:Mgr ?mgr. ?mgr f:Dept ?mdept. ?dept f:Dname ?edname. ?mdept f:Dname ?mdname. FILTER (?dept != ?mdept) }
在关系术语中,这是员工和 salgrade 表之间的 theta 连接。
select ?ename ?grade where { ?emp rdf:type f:emp; foaf:surname ?ename; f:Sal ?sal. ?salgrade rdf:type f:salgrade; f:LoSal ?low; f:HiSal ?high; f:Grade ?grade. FILTER (?sal >= ?low && ?sal <= ?high) }
一个新的前缀简化了通过 URI 引用单个资源的过程。
prefix e: <http://www.cems.uwe.ac.uk/empdept/emp/> select ?sal where { e:7900 f:Sal ?sal. }
是 的简写。
select ?sal where { <http://www.cems.uwe.ac.uk/empdept/emp/7900> f:Sal ?sal. }
我们也可以引入一个默认命名空间
prefix : <http://www.cems.uwe.ac.uk/empdept/concept/> select ?name ?sal ?dno ?job where { ?emp rdf:type :emp; foaf:surname ?name; :Sal ?sal; :Dept ?dept; :Job ?job. ?dept :DeptNo ?dno. }
并使用缩写 **a** 代表 rdf:type
prefix : <http://www.cems.uwe.ac.uk/empdept/concept/> select ?name ?sal ?dno ?job where { ?emp a :emp; foaf:surname ?name; :Sal ?sal; :Dept ?dept; :Job ?job. ?dept :DeptNo ?dno. }
如果我们不需要返回资源本身,它可以是匿名的
prefix : <http://www.cems.uwe.ac.uk/empdept/concept/> select ?name ?sal ?dno ?job where { [ a :emp; foaf:surname ?name; :Sal ?sal; :Dept ?dept; :Job ?job ]. ?dept :DeptNo ?dno. }
聚合函数,如 count() 和 sum() 以及 GROUP BY 子句,在 SPARQL 1.0 中没有定义,尽管它们在某些服务(例如 Talis 平台)中可用,以先于 SPARQL 1.1 中的标准化。
select (count(?dept) as ?count) where { ?dept rdf:type f:dept. }
select distinct ?dept (count(?emp) as ?count) where { ?dept a f:dept. ?emp f:Dept ?dept. } group by ?dept
三元组数据模型的统一性使我们能够以非常通用的方式查询数据集,这在我们对数据一无所知时非常有用。
select * where { ?s ?p ?o }
这对真实数据集来说是不切实际的,但可以通过限制返回的三元组数量来获取三元组样本。
select * where { ?s ?p ?o } LIMIT 20
select ?prop ?val where { ?emp rdf:type f:emp. ?emp ?prop ?val. }
select distinct ?type where { ?s a ?type }
这表明定义 emp 词汇的三元组在同一个数据集中。
select distinct ?prop where { ?s ?prop ?o }
select distinct ?type where { ?s f:Sal ?v. ?s a ?type. }
select distinct ?type where { ?s f:Sal ?o. ?o a ?type. }
此查询仅查找数据集中作为类型实例的范围。Sal 的范围是 xs:integer,但用 SPARQL 查询很难发现这一点。
select distinct ?type where { ?s f:Mgr ?o. ?o a ?type. }
哪些属性具有给定类型作为其域?
[edit | edit source]select distinct ?prop where { ?s a f:salgrade. ?s ?prop []. }
模式查询
[edit | edit source]模式数据的存在使 SPARQL 可以用来查询这些元数据。结果可以与直接查询数据的结果进行比较。
哪些属性具有给定类型的域?
[edit | edit source]select ?prop where { ?prop rdfs:domain f:emp. }
请注意,这仅返回了 empdept 词汇表中的属性,而不是原始数据中使用的 foaf name 属性。
员工有哪些整数属性?
[edit | edit source]select ?prop where { ?prop rdfs:domain f:emp. ?prop rdfs:range xs:integer. }
哪些类型的资源有薪资?
[edit | edit source]select ?type where { f:Sal rdfs:domain ?type. }
可以对数据和词汇表进行查询
MANAGER 有哪些字面属性?
[edit | edit source]select DISTINCT ?prop where { ?x f:Job "MANAGER". ?x a ?type. ?prop rdfs:domain ?type. ?prop rdfs:range rdfs:literal. }
待办事项
[edit | edit source]- 示例 RDF 缺少语言标签,这些标签是说明 lang() 函数所必需的
- 所有查询应与 SQL 和 XQuery 等效项一起移至代码列表