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 等效項一起移至程式碼列表