SPARQL/表示式和函式
BIND( expression AS ?variable ). 語句可用於將表示式的結果分配給變數(通常是新變數,但您也可以覆蓋現有變數)。
# Persons died by capital punishment
SELECT ?person ?personLabel ?personDescription ?age
WHERE
{
?person wdt:P31 wd:Q5;
wdt:P569 ?born;
wdt:P570 ?died;
wdt:P1196 wd:Q8454.
BIND(?died - ?born AS ?ageInDays).
BIND(?ageInDays/365.2425 AS ?ageInYears).
BIND(FLOOR(?ageInYears) AS ?age).
# or, as one expression:
#BIND(FLOOR((?died - ?born)/365.2425) AS ?age).
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
BIND 還可以用於將常量值簡單地繫結到變數,以提高可讀性。例如,查詢所有女性牧師的查詢
SELECT ?woman ?womanLabel
WHERE
{
?woman ?instanceOf ?human;
?sexOrGender ?female;
?occupation ?priest.
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
# linking to wikidata Q and P codes
BIND(wdt:P31 AS ?instanceOf).
BIND(wd:Q5 AS ?human).
BIND(wdt:P21 AS ?sexOrGender).
BIND(wd:Q6581072 AS ?female).
BIND(wdt:P106 AS ?occupation).
BIND(wd:Q42603 AS ?priest).
}
以上結果與以下結果相同
SELECT ?woman ?womanLabel
WHERE
{
?woman wdt:P31 wd:Q5; # instance of human
wdt:P21 wd:Q6581072; # sex or gender female
wdt:P106 wd:Q42603. # occupation priest
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
IF( condition, thenExpression, elseExpression ) 表示式用於根據條件分配不同的值。
例如,為了計算年齡,精確到天。在表示式 BIND( .... - (IF( condition,1,0 ) AS ?age) 中,條件確定從 ?age 中減去 1 或 0(無),具體取決於出生日期和死亡日期的月份和日期。
# Query to find all musicians who have already died
# calculate their age (full years) at death
# count how many of them died at each age
#defaultView:LineChart
SELECT ?age (COUNT (DISTINCT ?a) AS ?count)
WHERE {
?a wdt:P31 wd:Q5. #instance of human
?a wdt:P106/wdt:P279 wd:Q639669. #occupation a subclass of musician
?a p:P569/psv:P569 ?birth_date_node.
?a p:P570/psv:P570 ?death_date_node.
?birth_date_node wikibase:timeValue ?birth_date.
?death_date_node wikibase:timeValue ?death_date.
BIND( YEAR(?death_date) - YEAR(?birth_date) -
IF(MONTH(?death_date)<MONTH(?birth_date) ||
(MONTH(?death_date)=MONTH(?birth_date) && DAY(?death_date)<DAY(?birth_date)),1,0) AS ?age )
# calculate the age, precisely to the day (times and timezones ignored)
FILTER(?age > 10 && ?age < 100). #ignore outlyers, several of which are probably errors
}
GROUP BY ?age
ORDER BY ?age
以下是一個將人口劃分為組的示例。#defaultView:Map 中的 ?layer 將其顯示為不同的顏色。
#Big cities, grouped into map layers by population
#defaultView:Map
SELECT DISTINCT ?city ?cityLabel (SAMPLE(?location) AS ?location) (MAX(?population) AS ?population) (SAMPLE(?layer) AS ?layer)
WHERE
{
?city wdt:P31/wdt:P279* wd:Q515;
wdt:P625 ?location;
wdt:P1082 ?population.
FILTER(?population >= 500000).
BIND(
IF(?population < 1000000, "<1M",
IF(?population < 2000000, "1M-2M",
IF(?population < 5000000, "2M-5M",
IF(?population < 10000000, "5M-10M",
IF(?population < 20000000, "10M-20M",
">20M")))))
AS ?layer).
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
GROUP BY ?city ?cityLabel
ORDER BY ?population
可以使用熟悉的數學運算子:+、-、*、/ 來新增、減去、乘以或除以數字。
運算子 <、>、=、<=、>= 可用於比較值。比較也為其他型別定義;例如,"abc" < "abd" 為真(詞法比較),"2016-01-01"^^xsd:dateTime > "2015-12-31"^^xsd:dateTime 和 wd:Q4653 != wd:Q283111 也是如此。不等式測試 ≠ 寫為 !=。! 也可以用作結果為布林值的函式的字首,如 !BOUND 和 !REGEX。
布林條件可以使用 &&(邏輯與:a && b 當 a 和 b 都為真時為真)和 ||(邏輯或:a || b 當 a 和 b 中的任何一個(或兩者)為真時為真)來組合。
例如 IF( ?a != ?b, ... , ... ) 和 IF( ?a = ?b && ?c = ?d, ... , ... )。
VALUES ?var { val1 ... } 語句生成一個具有一個或多個值的變數。這些值可以是任何型別,如數字、字串,甚至專案,如 VALUES ?number { 1 2 3 }、VALUES ?abc { "a" "b" "c" } 或 VALUES ?city { wd:Q84 wd:Q90 }.。
SELECT ?city ?cityLabel WHERE {
VALUES ?city { wd:Q84 wd:Q90 }. # London, Paris
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
值也可以具有更多維度。維度透過 ( ) 分組,如 VALUES ( ?varA ?varB ... ) { ( valA1 valB1 ... ) ... }。
SELECT ?country ?capital WHERE {
VALUES ( ?country ?capital ) {
( "United Kingdom" "London" )
( "France" "Paris" )
( "Etc" UNDEF ) # Use UNDEF for an undefined value
}
}
SPARQL 中的每個值都有一個型別,它告訴您值的型別以及您可以對其進行的操作。最重要的型別是
- 專案,如
wd:Q42,代表 道格拉斯·亞當斯 (Q42). - 布林值,具有兩個可能的值
true和false。布林值不會儲存在語句中,但許多表達式會返回布林值,例如2 < 3(true) 或"a" = "b"(false)。 - 字串,一段文字。字串文字用雙引號括起來。
- 單語文字,帶語言標籤的字串。在文字中,您可以在字串後面新增一個
@符號來新增語言標籤,例如"Douglas Adams"@en。 - 數字,可以是整數 (
1) 或小數 (1.23)。 - 日期。可以透過在 ISO 8601 日期字串中新增
^^xsd:dateTime(區分大小寫 -^^xsd:datetime不起作用!)來寫入日期字面值:"2012-10-29"^^xsd:dateTime。
# Date related properties of Bach
SELECT ?predicate ?pLabel ?object
WHERE
{
wd:Q1339 ?predicate ?object. # Bach
FILTER(DATATYPE(?object) = xsd:dateTime).
BIND( IRI(REPLACE( STR(?predicate),"prop/direct/","entity/" )) AS ?p).
# or ?p wikibase:directClaim ?predicate.
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
ORDER BY ?object
一些資料型別是 rdf:langString、xsd:string、xsd:integer、xsd:dateTime、xsd:decimal 或 "<http://www.opengis.net/ont/geosparql#wktLiteral>"。
STR
[edit | edit source]STR( value ) 函式將值轉換為字串。它還會解析 字首,例如 wd:Q1339 將被轉換為 http://www.wikidata.org/entity/Q1339。它的反向操作是 IRI( string ),它將字串轉換為 IRI。
SELECT ?item ?itemLabel ?string ?stringLabel ?iri ?iriLabel
WHERE {
VALUES ?item { wd:Q1339 }.
BIND( STR(?item) AS ?string ).
BIND( IRI(?string) AS ?iri ).
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
IRI
[edit | edit source]IRI( string ),它透過應用 字首 將字串轉換為 IRI。
在下面的示例中,像 wdt:P569 這樣的謂詞被轉換為字串 http://www.wikidata.org/prop/direct/P569。要獲取謂詞的標籤,首先需要將其替換為實體(http://www.wikidata.org/entity/P569),然後使用 IRI 轉換為 wd:P569。然後可以將它的標籤顯示為 "出生日期 (P569)"。
# Date related properties of Bach
SELECT ?object ?predicate ?string ?entity ?p ?pLabel
WHERE
{
wd:Q1339 ?predicate ?object. # Bach
FILTER(DATATYPE(?object) = xsd:dateTime).
BIND( STR(?predicate) AS ?string ).
BIND( REPLACE( ?string,"prop/direct/","entity/" ) AS ?entity ).
BIND( IRI(?entity) AS ?p ).
# or all on one line:
# BIND( IRI(REPLACE( STR(?predicate),"prop/direct/","entity/" )) AS ?p).
# This can also be written as: ?p wikibase:directClaim ?predicate.
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
ORDER BY ?object
LANG
[edit | edit source]LANG( string ) 函式檢索 標籤、描述、別名 和 單語文字 的語言標籤。
#Countries in European Union with native name and language
SELECT ?country ?countryLabel ?nativename ?language
WHERE
{
wd:Q458 wdt:P150 ?country. # European Union contains administrative territorial entity
OPTIONAL { ?country wdt:P1705 ?nativename.
BIND( LANG(?nativename) AS ?language). }
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
ORDER BY DESC(?language)
BOUND
[edit | edit source]BOUND( variable ) 函式如果變數繫結到值則返回 true。否則返回 false。BOUND 表示式經常與 IF(condition,thenExpression,elseExpression) 表示式一起使用。例如,假設您有一個顯示一些人的查詢,並且您希望顯示他們的 筆名 (P742)(如果他們有的話),而不是僅僅顯示他們的標籤,只有在沒有筆名的情況下才使用標籤。為此,您在 OPTIONAL 子句中選擇筆名(它必須是可選的 - 您不希望丟棄沒有筆名的結果),然後使用 BIND(IF(BOUND(… 來選擇筆名或標籤。
SELECT ?writer ?label
WHERE
{
?writer wdt:P31 wd:Q5; # French writer
wdt:P27 wd:Q142;
wdt:P106 wd:Q36180;
wdt:P569 ?dob.
FILTER("1751-01-01"^^xsd:dateTime <= ?dob && ?dob < "1801-01-01"^^xsd:dateTime) # born in the second half of the 18th century
?writer rdfs:label ?writerLabel. # get the English label
FILTER(LANG(?writerLabel) = "en")
OPTIONAL { ?writer wdt:P742 ?pseudonym. } # get the pseudonym, if it exists
BIND(IF(BOUND(?pseudonym),?pseudonym,?writerLabel) AS ?label). # bind the pseudonym, or if it doesn’t exist the English label, as ?label
}
IN 和 NOT IN
[edit | edit source]value IN( list of values ) 函式檢查值是否在值列表中找到。例如 2 IN( 1, 2, 3 ) 為 true。類似的函式 value NOT IN( list of values ) 檢查值是否不在值列表中找到。
# Railway stations in London or Paris
SELECT ?cityLabel ?station ?stationLabel ?location
WHERE {
?station wdt:P31 wd:Q55488. # is a railway station
?station wdt:P131* ?city.
?station wdt:P625 ?location
FILTER( ?city IN(wd:Q84, wd:Q90) ). # in London or Paris
SERVICE wikibase:label { bd:serviceParam wikibase:language "en,fr". }
}
isBLANK
[edit | edit source]isBLANK( variable ) 表示式檢查值是否為“未知值”。
#Demonstrates "unknown value" handling
SELECT ?human ?humanLabel
WHERE
{
?human wdt:P21 ?gender
FILTER isBLANK(?gender) .
SERVICE wikibase:label { bd:serviceParam wikibase:language "en" }
}
維基資料值也可以具有特殊值“無值”。對於普通三元組,這隻會導致結果缺失。
# persons who were stateless (country of citizenship: no value) for some time (start time and end time qualifiers)
SELECT ?person ?personLabel ?start ?end
WHERE {
?person wdt:P31 wd:Q5;
p:P27 [
a wdno:P27; # no value for country of citizenship
pq:P580 ?start;
pq:P582 ?end
].
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
ORDER BY DESC(?end - ?start)
字首 wdno: 選擇“無值”節點。
程式碼 a 是一個特殊詞。
字串函式
[edit | edit source]STRLEN
[edit | edit source]STRLEN( string ) 函式返回字串的長度。例如,STRLEN(?name) 其中 ?name 為 "ABC" 將返回 3。
SUBSTR
[edit | edit source]SUBSTR( string, beginposition, stringlength ) 函式返回字串的子字串,該子字串從 beginposition 標記的位置開始,並且具有指示的長度。例如,SUBSTR( ?name,2,3 ) 其中 ?name = "ABCDEFGH" 將返回 "BCD"。沒有長度的子字串,例如 SUBSTR( ?name,2 ) 將返回 "BCDEFGH"。
UCASE
[edit | edit source]UCASE( string ) 函式返回大寫字串。例如,字串 "Abc" 將返回為 "ABC"。
LCASE
[edit | edit source]LCASE( string ) 函式返回小寫字串。例如,字串 "Abc" 將返回為 "abc"。
STRSTARTS
[edit | edit source]STRSTARTS( string, comparestring ) 函式檢查字串是否以比較字串開頭。例如,STRSTARTS( "ABCDEFGH", "ABC" ) 返回 true,表示字串以 "ABC" 開頭。
STRENDS
[edit | edit source]STRENDS( string, comparestring ) 函式檢查字串是否以比較字串結尾。例如,STRENDS( "ABCDEFGH", "FGH" ) 返回 true,表示字串以 "FGH" 結尾。
CONTAINS
[edit | edit source]CONTAINS( string, comparestring ) 函式檢查字串是否包含比較字串。例如,CONTAINS( "ABCDEFGH", "DEF" ) 返回 true,表示字串包含 "DEF"。
STRBEFORE
[edit | edit source]STRBEFORE( string, comparestring ) 函式返回比較字串之前字串的一部分。例如,STRBEFORE( "ABCDEFGH", "DEF" ) 返回 "ABC"。如果未找到比較字串,則返回 ""。
STRAFTER
[edit | edit source]STRAFTER( string, comparestring ) 函式返回比較字串之後字串的一部分。例如,STRAFTER( "ABCDEFGH", "DEF" ) 返回 "GH"。如果未找到比較字串,則返回 ""。
ENCODE_FOR_URI
[edit | edit source]ENCODE_FOR_URI( string ) 函式將字串中的特殊字元轉換為可在網路 URL 中使用的字元。例如,ENCODE_FOR_URI( "ABC DËFGH" ) 返回 "ABC%20D%C3%8BFGH"。該函式的反函式是 wikibase:decodeUri( string )。
CONCAT
[edit | edit source]CONCAT( string1, string2 ... ) 函式返回兩個或多個字串的串聯。例如,CONCAT( "ABCDEFGH", "XYZ" ) 返回 "ABCDEFGHXYZ"。
LANGMATCHES
[edit | edit source]函式 LANGMATCHES( languagetag, languagerange ) 檢查語言標籤是否與語言範圍匹配。例如,這段程式碼 FILTER LANGMATCHES( LANG(?label), "fr" ). 篩選法語標籤。它類似於 FILTER (LANG(?label) = "fr").,區別在於 LANGMATCHES 過濾器還會輸出帶有區域的語言標籤,例如 "fr-BE",而 (FILTER (LANG(?label) = "fr"). 僅輸出帶有精確標籤 "fr" 的字串。語言範圍為 "*" 匹配任何非空的語言標籤字串。
函式 REGEX( string, pattern, flag ) 檢查字串是否與模式匹配。它主要用在 FILTER 子句中,例如 FILTER REGEX( string, pattern ).。
模式可能包含不同的特殊字元。Blazegraph 例項(如 Wikidata 查詢服務)將模式解釋為 Java Pattern,[1] 它是 ICU 正則表示式的子集。下表列出了最常見的特殊字元
|
|
|
flag 是可選的。flag "i" 表示匹配不區分大小寫。
# Names of human settlements ending in "-ow" or "-itz" in Germany
#defaultView:Map
SELECT DISTINCT ?item ?itemLabel ?coord
WHERE
{
?item wdt:P31/wdt:P279* wd:Q486972; # instance/subclass of human settlement
wdt:P17 wd:Q183; # Germany
rdfs:label ?itemLabel;
wdt:P625 ?coord;
FILTER (LANG(?itemLabel) = "de").
FILTER REGEX (?itemLabel, "(ow|itz)$").
}
LIMIT 1000
示例
- 標題可能是押韻的
FILTER(REGEX(?title, "^\\w*(\\w{3})(\\W+\\w*\\1)+$", "i") && !REGEX(?title, "^(\\w+)(\\W+\\1)+$", "i")). - 標題是頭韻
FILTER(REGEX(STR(?title), "^(\\p{L})\\w+(?:\\W+\\1\\w+){2,}$", "i")).
PS:單個 \ 用作字串中的轉義符號,因此 \\ 用於表示單個 \。
函式 REPLACE( string, pattern, replacement, flag ) 在將 string 中所有出現的 pattern 替換為 replacement 後返回字串。pattern 的解釋方式與 REGEX 中相同。replacement 可以包含 $n 或 ${name},它們將被模式中相應的編號或命名捕獲組 替換。[1] 可選的 flag 會影響正則表示式模式,就像 REGEX() 的 flag 引數一樣。例如,REPLACE( "ABCDEFGH", "DEF", "_def_" ) 返回 "ABC_def_GH"。REPLACE( "ABCDEFGH", "[AEIOU]", "" ) 從原始字串中刪除所有母音。
函式 ABS( number ) 返回數字的絕對值。例如,ABS( -1 ) 返回 1。
函式 ROUND( number ) 返回數字的四捨五入值。例如,ROUND( 1.4 ) 返回 1,而 ROUND( 1.6 ) 返回 2。
函式 CEIL( number ) 返回最大的數字(向上取整)。例如,CEIL( 1.4 ) 和 CEIL( 1.6 ) 都返回 2。
函式 FLOOR( number ) 返回最小的數字(向下取整)。例如,FLOOR( 1.4 ) 和 FLOOR( 1.6 ) 都返回 1。
函式 RAND( ) 返回 0 到 1 之間的隨機值。例如,RAND( ) 返回 0.7156405780739334。
函式 COUNT、MIN、MAX、AVG 和 SUM 只能用作 聚合函式。
# average age of painters by century
SELECT ?century (AVG(?age) AS ?average_age) (ROUND(AVG(?age)) AS ?rounded_average_age)
WHERE
{
?item wdt:P31 wd:Q5. # is a human
?item wdt:P106 wd:Q1028181. # occupation painter
?item wdt:P569 ?born.
?item wdt:P570 ?died.
FILTER( ?died > ?born ).
BIND( (?died - ?born)/365.2425 AS ?age )
BIND( FLOOR(YEAR(?born)/100)*100 AS ?century )
}
GROUP BY ?century
ORDER BY ?century
例如,BIND( MAX( ?var1, ?var2 ) AS ?max) 不起作用。相反,請使用表示式 BIND( IF( ?var1>?var2, ?var1, ?var2 ) AS ?max)。
函式 NOW( ) 返回當前日期和時間。
使用 NOW() + "P1D"^^xsd:duration 之類的結構,可以從當前日期新增或減去天數。
NOW() + "P1M"^^xsd:duration 將新增 1 個月。
NOW() + "P1Y"^^xsd:duration 將新增 1 年。
您可以使用 "P1Y1M1DT0H0M0.000S"^^xsd:duration 新增或減去任何組合的年、月、日,甚至小時、分鐘和秒。
函式 YEAR( datevalue ) 返回日期值的年份。函式 MONTH 和 DAY 返回月份或日期。
函式 HOURS( datevalue ) 返回日期值的小時。函式 MINUTES 和 SECONDS 返回分鐘或秒。
目前 Wikidata 不以小時、分鐘或秒的形式儲存日期值。
函式 TIMEZONE( datevalue ) 返回日期值的時區。目前在 Wikidata 中,所有日期的 TIMEZONE 都是 "PT0S",表示 UTC。其他有效值介於 -PT14H 和 PT14H 之間,表示以小時為單位的時區偏移量。
函式 TZ( datevalue ) 返回日期值的時區,以簡單的文字形式表示。目前在 Wikidata 中,所有日期的 TZ 都是 "Z",表示 UTC。
日期示例
# Query to find all musicians who have already died
# calculate their age (full years) at death
# count how many of them died at each age
#defaultView:LineChart
SELECT ?age (COUNT (DISTINCT ?a) AS ?count)
WHERE {
?a wdt:P31 wd:Q5. #instance of human
?a wdt:P106/wdt:P279 wd:Q639669. #occupation a subclass of musician
?a p:P569/psv:P569 ?birth_date_node.
?a p:P570/psv:P570 ?death_date_node.
?birth_date_node wikibase:timeValue ?birth_date.
?death_date_node wikibase:timeValue ?death_date.
BIND( YEAR(?death_date) - YEAR(?birth_date) -
IF(MONTH(?death_date)<MONTH(?birth_date) ||
(MONTH(?death_date)=MONTH(?birth_date) && DAY(?death_date)<DAY(?birth_date)),1,0) AS ?age )
# calculate the age, precisely to the day (times and timezones ignored)
FILTER(?age > 10 && ?age < 100). #ignore outliers, several of which are probably errors
}
GROUP BY ?age
ORDER BY ?age
函式 geof:distance 返回兩點之間的距離,以公里為單位。
使用示例
# distance between 2 cities
SELECT ?city1 ?city1Label ?location1 ?city2 ?city2Label ?location2 ?dist
WHERE
{
VALUES ?city1 { wd:Q84 }. # London
VALUES ?city2 { wd:Q90 }. # Paris
?city1 wdt:P625 ?location1.
?city2 wdt:P625 ?location2.
BIND(geof:distance(?location1, ?location2) as ?dist)
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
函式 geof:longitude 和 geof:latitude 將一個 Well-Known Text 文字 (<http://www.opengis.net/ont/geosparql#wktLiteral>) 的點幾何分別轉換為它的經度和緯度。
使用示例
# Museums in Barcelona with coordinates
SELECT ?item ?itemLabel ?coord ?lon ?lat
WHERE
{
?item wdt:P131 wd:Q1492; # in the administrative territory of Barcelona
wdt:P31 wd:Q33506; # is a museum
wdt:P625 ?coord.
BIND(geof:longitude(?coord) AS ?lon)
BIND(geof:latitude(?coord) AS ?lat)
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
也可以使用 wikibase:geoLongitude 和 wikibase:geoLatitude 限定符來檢索座標節點的經度和緯度。有關解釋,請參見 此處。
# Museums in Barcelona with coordinates
SELECT ?item ?itemLabel ?coord ?lon ?lat
WHERE
{
?item wdt:P131 wd:Q1492; # in the administrative territory of Barcelona
wdt:P31 wd:Q33506; # is a museum
p:P625 [
ps:P625 ?coord;
psv:P625 [
wikibase:geoLongitude ?lon;
wikibase:geoLatitude ?lat;
]
].
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
程式碼 BIND("[AUTO_COORDINATES]" as ?loc) 會返回當前位置,如果您允許瀏覽器使用它。
# Drinking establishments near me
SELECT DISTINCT ?pub ?pubLabel ?dist
WHERE
{
BIND("[AUTO_COORDINATES]" as ?loc) .
SERVICE wikibase:around {
?pub wdt:P625 ?location .
bd:serviceParam wikibase:center ?loc.
bd:serviceParam wikibase:radius "1" .
}
FILTER EXISTS { ?pub wdt:P31/wdt:P279* wd:Q5307737 }
SERVICE wikibase:label { bd:serviceParam wikibase:language "en" }
BIND(geof:distance(?loc, ?location) as ?dist)
} ORDER BY ?dist
有關 COUNT、MIN、MAX、SUM、AVG、SAMPLE 和 GROUP_CONCAT,請參見 聚合函式
- ↑ a b Wikidata 查詢服務使用 Blazegraph 的一個 Wikimedia 分支,它 依賴於 OpenJDK 8。其他例項可能執行不同版本的 Java,其 Unicode 支援級別也不同。