1 Jena搭建SPARQL查詢RDF數據
1.1 Jena概要
· SPARQL是W3C的RDF數據工作組設計的一種查詢語言和協議,用於RDF數據的查詢。經過類似於JDK安裝時候的配置,可以在命令行運行SPARQL查詢,也可以在安裝了Jena API之后,在Java程序用使用SPARQL查詢。
1.2 Jena環境搭建
· 到oracle官網上下載最新版本的JDK然后安裝,地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html
· 可以從http://jena.sourceforge.net免費獲得Jena的最新版本,或者直接從本站下載:jena-2.6.4.zip。
· 將下載好的jena解壓到摸個目錄,如C:\soft\develop\jena
· 添加環境變量,鼠標右鍵單擊【我的電腦】-【屬性】-【高級】-【環境變量】
■ 添加JDK系統變量PATH -> 值C:\Program Files (x86)\Java\jdk1.7.0_21\bin
■ 添加Jena系統變量PATH -> 值C:\soft\develop\jena\bat
■ 添加Jena根目錄JENAROOT ->C:\soft\develop\jena
· 如何上面沒執行錯誤的話,在命令行執行sparql會返回
No query string or query file
如果執行sparql –h(或者sparql –help)就會返回命令sparql的幫助信息。
1.3 執行一個簡單的查詢
· SPARQL查詢語句的執行格式是:
sparql --data=<file> --query=<query>
file是要查詢的數據源,RDF文件或者RDF圖文件;
query是查詢語句文件,以.rq為文件后綴。
· 數據源,一個RDF文件r1.rdf,文檔描述一些簡單的人名信息,下面是類似三元組形式的數據表示。
<?xml version="1.0"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:vCard="http://www.w3.org/2001/vcard-rdf/3.0#">
<rdf:Description rdf:about="http://somewhere/MattJones/">
<vCard:FN>Matt Jones</vCard:FN>
<vCard:N rdf:parseType="Resource">
<vCard:Family>Jones</vCard:Family>
<vCard:Given>Matthew</vCard:Given>
</vCard:N>
</rdf:Description>
<rdf:Description rdf:about="http://somewhere/RebeccaSmith/">
<vCard:FN>Becky Smith</vCard:FN>
<vCard:N rdf:parseType="Resource">
<vCard:Family>Smith</vCard:Family>
<vCard:Given>Rebecca</vCard:Given>
</vCard:N>
</rdf:Description>
<rdf:Description rdf:about="http://somewhere/JohnSmith/">
<vCard:FN>John Smith</vCard:FN>
<vCard:N rdf:parseType="Resource">
<vCard:Family>Smith</vCard:Family>
<vCard:Given>Jones</vCard:Given>
</vCard:N>
</rdf:Description>
<rdf:Description rdf:about="http://somewhere/SarahJones/">
<vCard:FN>Sarah Jones</vCard:FN>
<vCard:N rdf:parseType="Resource">
<vCard:Family>Jones</vCard:Family>
<vCard:Given>Sarah</vCard:Given>
</vCard:N>
</rdf:Description>
</rdf:RDF>
· 查詢語句q1.rq
SELECT ?x
WHERE { ?x <http://www.w3.org/2001/vcard-rdf/3.0#FN> "John Smith" }
· 使用上面的查詢語句查詢r1.rdf文件中的數據的命令行語句就是
sparql --data=r1.rdf --query=q1.rq
返回結果是:
---------------------------------
| x |
=================================
| <http://somewhere/JohnSmith/> |
---------------------------------
· 在執行上面的查詢時,要保證數據文件和查詢文件在當前目錄下,否則命令中應該包括完整路徑,即:
sparql --data=c:\sparql\r1.rdf --query=c:\sparql\q1.rq
2 對查詢語句和查詢結果的理解
· 查詢語句包括查詢信息的名稱以及名稱應該符合的條件。條件子句以三元組形式出現,按照<主語,謂語,賓語>的順序排列。查詢條件也成為一個模式(Pattern)。查詢的結果實際就是條件三元組與數據文件(或RDF圖)中RDF三元組匹配的結果。
· 語句中的 ? 加一個字母表示該字母是一個變量,比如 ?x,在SELECT后面的變量會顯示在查詢結果中,作為列名稱出現。
· 實際上,做到這一步之后,所有的事情只是修改模式,給模式添加一些條件了,非常簡單。
2.1 命名空間的簡寫替代
· 如果查詢所有具有名字的實例以及該實例的名字,那么查詢語句如下
SELECT ?x ?fname
WHERE {?x <http://www.w3.org/2001/vcard-rdf/3.0#FN> ?fname}
· 注意,“?x ?fname”之間是空格,不是逗號。如果有多個模式三元組,那么三元組之間用點號“.”隔開,比如
SELECT ?givenName
WHERE
{ ?y <http://www.w3.org/2001/vcard-rdf/3.0#Family> "Smith" .
?y <http://www.w3.org/2001/vcard-rdf/3.0#Given> ?givenName .}
· 這時候,模式中的謂詞的URI都帶一個長長的命名空間字符串,“http://www.w3.org/2001/vcard-rdf/3.0#”,
能用一個簡單的單詞代替它應該會比較簡單。實現簡寫URI的的語法是這樣的:
PREFIX vcard:<http://www.w3.org/2001/vcard-rdf/3.0#>
SELECT ?givenName
WHERE
{ ?y vcard:Family "Smith" .
?y vcard:Given ?givenName .
}
· 語句PREFIX vcard:<http://www.w3.org/2001/vcard-rdf/3.0#> 定義了一個前綴單詞vcard,在查詢語句中,它與后面的命名空間等價。
2.2 過濾查詢結果
· 在查詢語句中添加過濾條件的語句是
FILTER regex(?x, "pattern" [, "flags"])
FILTER是聲明過濾,?x是過濾模式作用的變量,后面的pattern是具體的限制條件,比如
PREFIX vcard: <http://www.w3.org/2001/vcard-rdf/3.0#>
SELECT ?g
WHERE
{ ?y vcard:Given ?g .
FILTER regex(?g, "r", "i") }
這是要查詢一些名字(Given Name),”r”表示,名字中必須出現的字母”r”或者”R”;”i”表示,對簽名的字母限制,默認不加對大小寫敏感,加上則對大小寫不敏感。上面查詢的結果是
-------------
| g |
=============
| "Rebecca" |
| "Sarah" |
-------------
· 對數值限制的一個例子是:請查詢r2.rdf文件
PREFIX info <http://somewhere/peopleInfo#>
SELECT ?resource
WHERE { ?resource info:age ?age .
FILTER (?age >= 24)}
查詢結果是:
------------------------------------------
| resource | age |
==========================================
| <http://somewhere/JohnSmith/> | 44 |
| <http://somewhere/RebeccaSmith/> | 30 |
------------------------------------------
2.3 可選的查詢信息optional information
· 在一些查詢中,一些需要返回的數據可能不存在,而這些不存在的數據所在的數據元素中有其他需要返回的信息,這時候就可以通過可選查詢信息進行查詢,比如:
PREFIX vcard: <http://www.w3.org/2001/vcard-rdf/3.0#>
SELECT ?name ?age
WHERE
{ ?person vcard:FN ?name .
OPTIONAL { ?person vcard:Age ?age }
}
這是要查詢一些名字和年齡,但有些人沒有年齡信息,也要返回名字。
於是,OPTIONAL表示,模式{ ?person info:age ?age } 是可選的,不是必須滿足的。
這個查詢的執行語句是
sparql --data=vc-db-2.rdf --query=q-opt1.rq
查詢結果是
-----------------------
| name | age |
=======================
| "Sarah Jones" | |
| "John Smith" | 44 |
| "Becky Smith" | 30 |
| "Matt Jones" | 18 |
-----------------------
如果去點關鍵字OPTIONAL,那么,查詢的結果就是
-----------------------
| name | age |
=======================
| "John Smith" | 44 |
| "Becky Smith" | 30 |
| "Matt Jones" | 18 |
-----------------------
有些人沒有年齡信息,那么,這些人的名字也不會被作為查詢結果返回。
2.4 對可選模式添加過濾條件
PREFIX vcard: <http://www.w3.org/2001/vcard-rdf/3.0#>
SELECT ?name ?age
WHERE
{ ?person vcard:FN ?name .
OPTIONAL { ?person vcard:Age ?age .
FILTER ( ?age > 24 ) }
}
這樣返回的信息是
-----------------------
| name | age |
=======================
| "Sarah Jones" | |
| "John Smith" | 44 |
| "Becky Smith" | 30 |
| "Matt Jones" | |
-----------------------
· 有些人沒有年齡信息("Sarah Jones"),有些人的年齡小於24("Matt Jones" ),他們的名字信息也會出現在查詢結果中。下面的查詢要求,如果有年齡信息,那么年齡必須大於24,否則不是期望的查詢結果。
PREFIX vcard:<http://www.w3.org/2001/vcard-rdf/3.0#>
SELECT ?name ?age
WHERE
{ ?person vcard:FN ?name .
OPTIONAL { ?person vcard:Age ?age . }
FILTER ( !bound(?age) || ?age > 24 )
}
語句 !bound(?age) || ?age > 24 的意思是,沒有(未綁定)age或者age大於24。如此,年齡小於24的"Matt Jones"就不會出現在這個查詢的結果中了。
-----------------------
| name | age |
=======================
| "Sarah Jones" | |
| "John Smith" | 44 |
| "Becky Smith" | 30 |
-----------------------
2.5 聯合查詢
· vCard詞匯表和FOAF詞匯表都可以表示人的信息,比如vCard中的vCard:FN, FOAF中的foaf:name.這一節介紹在一個RDF圖同時用vCard:FN和foaf:name表示人的信息時,如何查詢相關數據。
注:vCard是電子商務中卡的一種文件格式標准,一般與郵件信息關聯。FOAF(http://xmlns.com/foaf/0.1/)是一種RDF的應用,所列網址有它的規范。
· 一個RDF文件,r3.rdf文件的的內容為
<?xml version="1.0"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:foaf="http://xmlns.com/foaf/0.1/"
xmlns:vCard="http://www.w3.org/2001/vcard-rdf/3.0#">
<rdf:Description rdf:about="http://somewhere/MattJones">
<foaf:name>Matt Jones</foaf:name>
</rdf:Description>
<rdf:Description rdf:about="http://somewhere/SarahJones">
<foaf:name>Sarah Jones</foaf:name>
</rdf:Description>
<rdf:Description rdf:about="http://somewhere/BeckySmith/">
<vCard:name>Becky Smith</vCard:name>
</rdf:Description>
<rdf:Description rdf:about="http://somewhere/JohnSmith/">
<vCard:name>John Smith</vCard:name>
</rdf:Description>
</rdf:RDF>
它只是分別用foaf:name和vcard:FN描述了四個人名,這一節的查詢將針對此文件。
· 查詢人名信息
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX vCard: <http://www.w3.org/2001/vcard-rdf/3.0#>
SELECT ?name
WHERE{
{ [] foaf:name ?name } UNION { [] vCard:FN ?name }
}
查詢結果是
-----------------
| name |
=================
| "Sarah Jones" |
| "Matt Jones" |
| "John Smith" |
| "Becky Smith" |
-----------------
一個等價的查詢語句是
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX vCard: <http://www.w3.org/2001/vcard-rdf/3.0#>
SELECT ?name
WHERE{
[] ?p ?name
FILTER ( ?p = foaf:name || ?p = vCard:FN ) }
· 記錄結果的來源,查詢語句和結果分別是
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX vCard: <http://www.w3.org/2001/vcard-rdf/3.0#>
SELECT ?name1 ?name2
WHERE{
{ [] foaf:name ?name1 } UNION { [] vCard:FN ?name2 }
}
---------------------------------
| name1 | name2 |
=================================
| "Sarah Jones" | |
| "Matt Jones" | |
| | "John Smith" |
| | "Becky Smith" |
---------------------------------
使用OPTIONAL
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX vCard: <http://www.w3.org/2001/vcard-rdf/3.0#>
SELECT ?name1 ?name2
WHERE{
?x ?a ?name
OPTIONAL { ?x foaf:name ?name1 }
OPTIONAL { ?x vCard:FN ?name2 }
}
查詢結果是:
---------------------------------
| name1 | name2 |
=================================
| "Matt Jones" | |
| "Sarah Jones" | |
| | "Becky Smith" |
| | "John Smith" |
---------------------------------
2.6 查詢命名的圖
· 圖是一個RDF數據集,不是一個完整的RDF文件。現在有三個圖
ds-dft.rdf
<?xml version="1.0"?>
<!DOCTYPE rdf:RDF [<!ENTITY xsd "http://www.w3.org/2001/XMLSchema#">]>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<rdf:Description rdf:about="ds-ng-1.rdf">
<dc:date rdf:datatype="&xsd;dateTime">2005-07-14T03:18:56+0100</dc:date>
</rdf:Description>
<rdf:Description rdf:about="ds-ng-2.rdf">
<dc:date rdf:datatype="&xsd;dateTime">2005-09-22T05:53:05+0100</dc:date>
</rdf:Description>
</rdf:RDF>
ds-ng-1.rdf
<?xml version="1.0"?>
<!DOCTYPE rdf:RDF [<!ENTITY xsd "http://www.w3.org/2001/XMLSchema#">]>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<rdf:Description rdf:about="">
<dc:title>Harry Potter and the Philospher's Stone</dc:title>
</rdf:Description>
<rdf:Description rdf:about="">
<dc:title>Harry Potter and the Chamber of Secrets</dc:title>
</rdf:Description>
</rdf:RDF>
ds-ng-2.rdf
<?xml version="1.0"?>
<!DOCTYPE rdf:RDF [<!ENTITY xsd "http://www.w3.org/2001/XMLSchema#">]>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<rdf:Description rdf:about="">
<dc:title>Harry Potter and the Sorcerer's Stone</dc:title>
</rdf:Description>
<rdf:Description rdf:about="">
<dc:title>Harry Potter and the Chamber of Secrets</dc:title>
</rdf:Description>
</rdf:RDF>
· 查詢語句是
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX : <.>
SELECT *{ ?s ?p ?o }
對圖的查詢是(PREFIX : <.>是為了格式化輸出???),
sparql --graph=ds-dft.rdf --namedgraph=ds-ng-1.rdf --namedgraph=ds-ng-2.rdf --query=ds-dft.rq
查詢結果是
---------------------------------------------------------------------
| s | p | o |
=====================================================================
| :ds-ng-2.rdf | dc:date | "2005-09-22T05:53:05+0100"^^xsd:dateTime |
| :ds-ng-1.rdf | dc:date | "2005-07-14T03:18:56+0100"^^xsd:dateTime |
---------------------------------------------------------------------
· 查詢指定圖
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX : <.>
SELECT ?title{
GRAPH :ds-ng-2.rdf
{ ?b dc:title ?title }}
查詢結果
---------------------------------------------
| title |
=============================================
| "Harry Potter and the Chamber of Secrets" |
| "Harry Potter and the Sorcerer's Stone" |
---------------------------------------------
2.7 SPARQL查詢結果集
· 四種形式的結果
■ SELECT – 返回一個表(table),Tutorial里介紹的主要是這種查詢
■ CONSTRUCT – 返回一個RDF圖
■ DESCRIBE – 返回一個RDF圖.
■ ASK – 布爾查詢
· 結果調整
■ Projection - 投影- 只保持選擇的變量
■ OFFSET/LIMIT - 偏移和限制 - 分解數字結果
■ ORDER BY - 排序
■ DISTINCT - 產生只有一行的一個組合變量和值.
