個人qq:1505979686,歡迎交流
參考:
算是剛捅破一層窗戶紙吧,之后會寫系列文章對sparql語法進行介紹。主要是對sparql規范的總結,結合DBpedia查詢接口進行示例。申明兩點:
- sparql同sql語法極其相似,對有sql基礎的人來說學起來應該很快,主要就是1)了解語法關鍵字的細微差別;2)對其功能架構有大致了解;
- 感覺sparql可以隨用隨查,沒必要死扣細節掌握全面(至少對馬上秋招的我來說是這樣),但是對其功能架構一定要了然於胸,知道他可以干什么,大致該怎么寫,細節再去查規范。
一.基本介紹
1.1 實體屬性
實體屬性分為3中:對象屬性、數據屬性、功能屬性。還有總的屬性Property。
select DISTINCT(?props) AS ?P
where{
?sub <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/1999/02/22-rdf-syntax-ns#Property> .
?sub <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?props
}
http://www.w3.org/1999/02/22-rdf-syntax-ns#Property
http://www.w3.org/2002/07/owl#ObjectProperty
http://www.w3.org/2002/07/owl#FunctionalProperty
http://www.w3.org/2002/07/owl#DatatypeProperty
1)數據屬性
年齡、性別和出生日期都是數據屬性,但是類型分別是整型、String和date。部分數據屬性值以^^
鏈接其類型。示例
//海明威數據屬性的鍵值對
select ?pred ?value
where{
<http://dbpedia.org/resource/Ernest_Hemingway> ?pred ?value .
?pred <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#DatatypeProperty> .
}
output:
http://dbpedia.org/ontology/deathDate
"1961-7-2"^^<http://www.w3.org/2001/XMLSchema#date>
2)對象屬性
對象屬性會有其取值范圍是對象,比如某人的老婆一定是人;
select ?pred,?range
where{
?pred <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#ObjectProperty> .
?pred <http://www.w3.org/2000/01/rdf-schema#range> ?range .
} limit 100
output:
http://dbpedia.org/ontology/birthPlace http://dbpedia.org/ontology/Place
http://dbpedia.org/ontology/thumbnail http://dbpedia.org/ontology/Image
http://dbpedia.org/ontology/academicAdvisor http://dbpedia.org/ontology/Person
二.關鍵字使用
關鍵字大小寫通用,主要介紹:`optional、
2.1 OPTIONAL 可選過濾
表示條件是可選的,可以使用多個OPTIONAL表示多個{}中的條件都是可選的
//如下,如果?sub有child屬性,則羅列出其屬性值,沒有的話就空出來
select ?sub ?value
where{
?sub <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://dbpedia.org/ontology/Person> .
optional{?sub <http://dbpedia.org/ontology/child> ?value }.
optional{...}
}
output:
...
http://dbpedia.org/resource/Junichirō_Koizumi http://dbpedia.org/resource/Shinjirō_Koizumi
http://dbpedia.org/resource/Junichirō_Koizumi http://dbpedia.org/resource/Kotaro_Koizumi
http://dbpedia.org/resource/Andreas_Ekberg
http://dbpedia.org/resource/Danilo_Tognon
...
2.2 order by 可選過濾
默認升序,使用DESC(?var1)可以在指定字段使用降序
select ?birthDate
where{
?sub <http://dbpedia.org/ontology/birthDate> ?birthDate .
FILTER REGEX(?birthDate,"^19")
} order by ?birthDate
output:
"1901-6-13"^^<http://www.w3.org/2001/XMLSchema#date>
"1901-6-14"^^<http://www.w3.org/2001/XMLSchema#date>
不同的字段使用不同的方式排序
select ?sub,?birthDate,?deadDate
where{
?sub <http://dbpedia.org/ontology/birthDate> ?birthDate .
?sub <http://dbpedia.org/ontology/deathDate> ?deadDate .
FILTER ( REGEX(?birthDate,"^19") && regex(?deadDate,"^19")).
} order by ?birthDate,DESC(?deadDate)
output:
http://dbpedia.org/resource/Grace_Hartman_(politician)
"1900-0-0"^^<http://www.w3.org/2001/XMLSchema#date>
1998-05-23
http://dbpedia.org/resource/Ho_Sin_Hang
"1900-0-0"^^<http://www.w3.org/2001/XMLSchema#date>
1997-12-04
http://dbpedia.org/resource/Fateh_Chand_Badhwar
"1900-0-0"^^<http://www.w3.org/2001/XMLSchema#date>
1995-10-10
2.3 篩選FILTER、HAVING
FILTER表示對結果集進行篩選,可以放在OPTIONAL子句中針對可選子句的結果集進行篩選。
1) 直接使用>,<,=,!=進行篩選,符號兩側可以是常量或者變量
select ?sub,?age
where{
?sub <http://dbpedia.org/ontology/birthDate> ?age .
filter (?age!='1861-7-2').
} limit 100
2)使用正則表達式 FILTER REGEX(?變量,"regex","param")
//類型值含有person,且不區分大小寫
select DISTINCT(?class) as ?class
where{
?sub <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?class
FILTER REGEX(?class,"person","i")
}
output:
http://xmlns.com/foaf/0.1/Person
http://dbpedia.org/ontology/Person
3)HAVING 對最后的結果集進行篩選
跟group by一塊使用,注意篩選的時候不能用別名。
//出生人數超過1000人的時間及出生人數統計
select ?birth,(COUNT(?birth) AS ?cou)
where{
?sub <http://dbpedia.org/ontology/birthDate> ?birth
}
group by ?birth
having (COUNT(?birth)>1000) //fixme:不能使用 having (?cou>1000)
output:
...
"1971-1-1"^^<http://www.w3.org/2001/XMLSchema#date>
1803
"1968-1-1"^^<http://www.w3.org/2001/XMLSchema#date>
1361
"1940-1-1"^^<http://www.w3.org/2001/XMLSchema#date>
1234
"1947-1-1"^^<http://www.w3.org/2001/XMLSchema#date>
1722
"1958-1-1"^^<http://www.w3.org/2001/XMLSchema#date>
1644
"1959-1-1"^^<http://www.w3.org/2001/XMLSchema#date>
1709
...
四.常用函數
1. 字符串
字符串的長度strlen(str)
、截取字符串substr("str",start_index,length/可選),字符出現的位置
字符串長度
//長度小於14的名字
select ?name,(strlen(?name) as ?nameLength)
where{
?sub <http://xmlns.com/foaf/0.1/givenName> ?name
filter (strlen(?name)<15)
} order by DESC(?nameLength)
"Clarence Brown"@en 14
"Brothers Grimm"@en 14
"Samuel Johnson"@en 14
截取字符串substr(datasource,start_index,length)
還不知道怎么查詢某個字母第一次出現在字符串中的位置,todo
- substr(datasource,start_index,length):length可以省略,表示截取從開始索引到最后的位置;
- 有些?var不是string類型的,需要用str(?var)轉化一下
//作家生辰
select (substr(str(?bir),1,4) AS ?birYear),(COUNT(?writer) as ?cou)
where{
?writer <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://dbpedia.org/ontology/Writer> .
?writer <http://dbpedia.org/ontology/birthDate> ?bir .
}group by substr(str(?bir),1,4)
having (COUNT(?writer)>1)
order by desc(COUNT(?writer))
output:
birYear cou
1947 586
1948 585
1951 577
group by+聚合字符串:group_concat(?sub ; separator=",")
用某個字段分組並且希望知道合並的記錄數以及將某個字段所有記錄合並為一個字段
//以首都分組,查詢首都對應的國家
select ?capital,(COUNT(?capital) as ?cou),(group_concat(?country ; separator=",") as ?countries)
where{
?country <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://dbpedia.org/ontology/Country> .
?country <http://dbpedia.org/ontology/capital> ?capital .
}group by ?capital
having (COUNT(?capital)>1)
output:
http://dbpedia.org/resource/Dresden
2
http://dbpedia.org/resource/Kingdom_of_Saxony,http://dbpedia.org/resource/Electorate_of_Saxony
http://dbpedia.org/resource/Beirut
2
http://dbpedia.org/resource/Lebanon,http://dbpedia.org/resource/Greater_Lebanon