SPARQL/基礎
SPARQL 看起來可能很複雜,但簡單基礎已經可以讓你走很遠 - 如果你願意,你可以在本章之後停止閱讀,你已經知道足夠編寫許多有趣的查詢。其他章節只是添加了更多主題的資訊,你可以用它們來編寫不同的查詢。它們中的每一個都將使你能夠編寫更棒的查詢,但它們都不是必需的 - 你可以隨時停止閱讀,並希望仍然能獲得大量有用的知識!
此外,如果你以前從未聽說過維基資料、SPARQL 或 WDQS,這裡簡要解釋一下這些術語。
- 維基資料是一個知識資料庫。它包含很多語句,例如“加拿大的首都為渥太華”或“蒙娜麗莎是油畫在楊木板上”或“金的熱導率為 25.418 焦耳每摩爾開爾文”。
- SPARQL 是一種用於知識資料庫的提問(查詢)語言。使用正確的資料庫,SPARQL 查詢可以回答諸如“音樂中最流行的調性是什麼?”或“哪個角色由最多演員扮演?”或“血型的分佈情況如何?”或“今年有哪些作家的作品進入公有領域?”。
- WDQS,即 維基資料查詢服務,將兩者結合在一起:你輸入 SPARQL 查詢,它在維基資料的資料庫上執行查詢並顯示結果。
一個簡單的 SPARQL 查詢如下所示
SELECT ?a ?b ?c
WHERE
{
x y ?a.
m n ?b.
?b f ?c.
}
SELECT 子句列出了你想要返回的變數(變數以問號開頭),而 WHERE 子句包含對它們的限制,主要是三元組的形式。維基資料(以及類似的知識資料庫)中的所有資訊都以三元組的形式儲存;當你執行查詢時,查詢服務會嘗試用實際值填充變數,以便生成的元組出現在知識資料庫中,併為它找到的每個變數組合返回一個結果。
三元組可以像句子一樣閱讀(這就是它以句號結尾的原因),包含一個主語、一個謂語和一個賓語
SELECT ?fruit
WHERE
{
?fruit hasColor yellow.
?fruit tastes sour.
}
此查詢的結果可能包括,例如,“檸檬”。在維基資料中,大多數屬性是“有”-型別的屬性,因此查詢可以改寫為
SELECT ?fruit
WHERE
{
?fruit color yellow.
?fruit taste sour.
}
讀起來就像“?fruit 有顏色‘黃色’”(不是“?fruit 是‘黃色’的顏色” - 請記住這對“父母”/“孩子”之類的屬性!)。
但是,這不是 WDQS 的好例子。味道是主觀的,所以維基資料沒有關於它的屬性。相反,讓我們考慮一下父母/孩子關係,它們大多是明確的。
假設我們想要列出巴洛克作曲家約翰·塞巴斯蒂安·巴赫的所有孩子。使用上面的查詢中的偽元素,你將如何編寫該查詢?
希望你得到類似這樣的東西
SELECT ?child
WHERE
{
# either this...
?child parent Bach.
# or this...
?child father Bach.
# or this.
Bach child ?child.
# (note: everything after a ‘#’ is a comment and ignored by WDQS.)
}
前兩個三元組表示 ?child 必須有父母/父親巴赫;第三個表示巴赫必須有孩子 ?child。讓我們暫時使用第二個。
那麼要把它變成一個真正的 WDQS 查詢,還需要做什麼呢?在維基資料中,專案和屬性不是由人類可讀的名稱來標識的,比如“父親”(屬性)或“巴赫”(專案)。(有充分的理由:“約翰·塞巴斯蒂安·巴赫”也是一位 德國畫家 的名字,而“巴赫”也可能指 姓氏、 法國公社、 水星隕石坑 等等)。相反,維基資料專案和屬性被分配了一個識別符號。要查詢專案的識別符號,我們 搜尋 專案並複製看起來像是我們正在尋找的專案的 Q 號碼(例如,基於描述)。要查詢屬性的識別符號,我們執行相同的操作,但搜尋“P:搜尋詞”而不是僅僅是“搜尋詞”,這將搜尋限制為屬性。這告訴我們,著名的作曲家約翰·塞巴斯蒂安·巴赫是 Q1339,而指定專案父親的屬性是 P22。
最後但同樣重要的是,我們需要包含字首。對於簡單的 WDQS 三元組,專案應該以 wd: 為字首,屬性應該以 wdt: 為字首。(但這僅適用於固定值 - 變數沒有字首!)。
將這些放在一起,我們得到了第一個真正的 WDQS 查詢
SELECT ?child
WHERE
{
# ?child father Bach
?child wdt:P22 wd:Q1339.
}
點選“試試吧”連結,然後在 WDQS 頁面上“執行”查詢。你得到了什麼?
| child |
|---|
| wd:Q57225 |
| wd:Q76428 |
| … |
好吧,這令人失望。你只看到識別符號。你可以點選它們檢視它們的維基資料頁面(包括人類可讀的標籤),但有沒有更好的方法來檢視結果呢?
好吧,事實證明,有! (反問句真是太好了!)。如果你在 WHERE 子句中包含魔法文字
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
你會得到額外的變數:對於查詢中的每個變數 ?foo,你現在還有一個變數 ?fooLabel,它包含 ?foo 背後的專案的標籤。如果你將它新增到 SELECT 子句中,你將得到專案及其標籤
SELECT ?child ?childLabel
WHERE
{
# ?child father Bach
?child wdt:P22 wd:Q1339.
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
嘗試執行該查詢 - 你應該不僅看到專案編號,而且還看到各種孩子的姓名。
| child | childLabel |
|---|---|
| wd:Q57225 | 約翰·克里斯托弗·弗里德里希·巴赫 |
| wd:Q76428 | 卡爾·菲利普·埃曼努埃爾·巴赫 |
| … | … |
這完成了基礎知識。嘗試透過改變屬性來修改它。