SPARQL/FILTER
FILTER(condition) 是可以插入 SPARQL 查詢中的一個子句,用於過濾結果。在括號內,您可以放置任何布林型別的表示式,並且只有表示式返回 true 的結果才會被使用。
例如,要獲取 2015 年出生的所有人類列表,我們首先獲取所有人類及其出生日期 -
SELECT ?person ?personLabel ?dob
WHERE
{
?person wdt:P31 wd:Q5;
wdt:P569 ?dob.
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
- 然後過濾結果,只返回出生日期年份為 2015 的結果。有兩種方法可以做到這一點:使用 YEAR 函式提取日期的年份,並測試它是否為 2015 -
FILTER(YEAR(?dob) = 2015).
- 或者檢查日期是否在 2015 年 1 月 1 日(含)和 2016 年 1 月 1 日(不含)之間。
FILTER("2015-01-01"^^xsd:dateTime <= ?dob && ?dob < "2016-01-01"^^xsd:dateTime).
我認為第一種方法更直接,但事實證明第二種方法快得多,所以讓我們使用它。
SELECT ?person ?personLabel ?dob
WHERE
{
?person wdt:P31 wd:Q5;
wdt:P569 ?dob.
FILTER("2015-01-01"^^xsd:dateTime <= ?dob && ?dob < "2016-01-01"^^xsd:dateTime).
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
FILTER 的另一個可能用法與標籤相關。標籤服務非常有用,如果您只是想顯示變數的標籤。但如果您想對標籤做一些操作 - 例如:檢查它是否以 “Mr. ” 開頭 - 您會發現它不起作用。
SELECT ?human ?humanLabel
WHERE
{
?human wdt:P31 wd:Q15632617. # fictional human
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
FILTER(STRSTARTS(?humanLabel, "Mr. ")). # This does not work
}
此查詢查詢所有 Q15632617 的例項,並測試它們的標籤是否以 "Mr. " 開頭(STRSTARTS 是 “字串開頭 [以]” 的縮寫;還有 STRENDS 和 CONTAINS)。此方法不起作用的原因是標籤服務在查詢評估期間非常晚才新增其變數;在我們嘗試根據 ?humanLabel 過濾時,標籤服務尚未建立該變數。
幸運的是,標籤服務不是獲取專案標籤的唯一方法。標籤也以普通三元組的形式儲存,使用謂詞 rdfs:label。當然,這意味著所有標籤,而不僅僅是英文標籤;如果我們只想要英文標籤,我們將不得不根據標籤的語言進行過濾。
FILTER(LANG(?label) = "en").
LANG 函式返回單語字串的語言,在這裡我們只選擇那些用英文表示的標籤。完整的查詢是
SELECT ?human ?humanLabel
WHERE
{
?human wdt:P31 wd:Q15632617; # fictional human
rdfs:label ?humanLabel.
FILTER(LANG(?humanLabel) = "en").
FILTER(STRSTARTS(?humanLabel, "Mr. ")).
}
我們使用 ?human rdfs:label ?label 三元組獲取標籤,將其限制為英文標籤,然後檢查它是否以 “Mr. ” 開頭。
讓我們為這些虛構的人新增影像。
SELECT ?human ?humanLabel ?image
WHERE
{
?human wdt:P31 wd:Q15632617; # fictional human
rdfs:label ?humanLabel.
FILTER(LANG(?humanLabel) = "en").
FILTER(STRSTARTS(?humanLabel, "Mr. ")).
OPTIONAL{ ?human wdt:P18 ?image. }
}
程式碼 OPTIONAL{ ?human wdt:P18 ?image. } 顯示了所有以 “Mr. ” 開頭的虛構人物,如果可用,則顯示影像。
要僅選擇以 “Mr. ” 開頭的帶有影像的虛構人物,可以使用程式碼 ?human wdt:P18 ?image.。
要選擇那些沒有影像的虛構人物,應使用程式碼 FILTER NOT EXISTS{ ?human wdt:P18 ?image. }
SELECT ?human ?humanLabel ?image
WHERE
{
?human wdt:P31 wd:Q15632617; # fictional human
rdfs:label ?humanLabel.
FILTER(LANG(?humanLabel) = "en").
FILTER(STRSTARTS(?humanLabel, "Mr. ")).
FILTER NOT EXISTS{ ?human wdt:P18 ?image. } # without images
}
SPARQL 中提供的另一種否定方式是 MINUS,它會評估其兩個引數,然後計算左側的解決方案,這些解決方案與右側的解決方案不相容。
SELECT ?human ?humanLabel ?image
WHERE
{
?human wdt:P31 wd:Q15632617; # fictional human
rdfs:label ?humanLabel.
FILTER(LANG(?humanLabel) = "en").
FILTER(STRSTARTS(?humanLabel, "Mr. ")).
MINUS{ ?human wdt:P18 ?image. } # without images
}