Wikimania 2023/SPARQL: access and analyze data from Wikidata
Cose da sapere per fare query semplici su Wikidata. Per fare una ricerca su Wikidata tramite query si parte dal sito query.wikidata.org (il link si trova anche nella sidebar di Wikidata). Nota: negli esempi, il testo preceduto da # è un commento che non interferisce con il codice della query (si possono inserire commenti anche nel query service).
Innanzitutto bisogna dire al query service cosa vogliamo ottenere come risultato. Lo si può fare inserendo una riga contenente la keyword SELECT seguita dalle variabili di nostro intresse.
Ad esempio, se vogliamo come risultato della nostra query una colonna con gli identificativi wikidata (quelli che iniziano con Q
):
A questo punto bisogna scegliere quali elementi estrarre dal database di Wikidata e possiamo farlo utilizzando la keyword WHERE e delle semplici parentesi graffe. Ad esempio, se volessi solo ed esclusivamente tutti i gatti domestici presenti su Wikidata dovrei scrivere la riga
dove ?item è una variabile, wdt: una proprietà (P31 = istanza di) e wd: uno specifico valore (Q146 = gatto domestico) per la proprietà. Questi tre elementi formano una tripla. È fondamentale il punto alla fine della riga.
Combinata alla riga SELECT vista prima, avremo quindi:
A questo punto abbiamo ottenuto un risultato machine readable, ma noi poveri umani vediamo solo un elenco di Q e numeri. Possiamo però chiedere gentilmente di restituire, insieme ai codici identificativi, anche le etichette in una lingua specifica (proviamo con l'italiano e, come alternativa, l'inglese). Bisogna quindi aggiungre un ?itemLabel alla prima riga (quella che inizia con SELECT) e introdurre una nuova riga, all'interno delle parentesi graffe della keyword WHERE, con una nuova keyword: SERVICE seguita da una stringa (che si può non imparare a memoria, basta copiarla dalle query di esempio, come quella dei gatti).
Al posto di "it" possiamo inserire "[AUTO_LANGUAGE]" per far sì che di default l'etichetta compaia nella lingua dell'interfaccia dell'utente (se esiste, altrimenti passa alla seconda scelta, in questo caso inglese (en
) che può essere sostituta con il codice di qualsiasi lingua. Si possono inserire ulteriori lingue come terza quarta, quinta scelta, separandole sempre con una virgola (I codici lingua utilizzabili sono quelli ISO 639-1 e ISO 639-2). Esempio:
Fin'ora abbiamo visto come estrarre elementi che rispettano una sola condizione (nel caso sopra, tutti i gatti domestici → istanza di = gatto domestico). Ma possiamo ovviamente fare richieste leggermente più complesse.
Per esempio, se volessimo cercare tutti i poeti (occupazione = poeta; P106 = Q49757) di cittadinanza italiana (Paese di cittadinanza = Italia; P27 = Q38), dovremmo inserire due righe diverse nella parentesi graffe del WHERE, anziché una sola:
In questo modo il risultato mostrerà tutti e solo gli elementi che rispettando entrambe le condizioni: poeti E cittadini italiani.
E se invece volessimo cercare elementi che rispettano una condizione OPPURE un'altra? Seguiamo l'esempio dei poeti: non ci interessano più solo i poeti con cittadinanza italiana, ma anche quelli con cittadinanza portoghese. In questo caso, dobbiamo introdurre una nuova keyword: UNION.
Da notare che UNION va inserito tra due righe chiuse in parentesi graffe, sempre all'interno delle graffe del WHERE.
Adesso vogliamo invece cercare tutti i poeti con cittadinanza italiana che hanno un coniuge presente su Wikidata. In questo caso non dobbiamo assegnare un valore specifico a una proprietà, ma possiamo assegnare una variabile, come per dire "tutti coloro i quali hanno un coniuge". Partendo dalla query dei poeti italiani, aggiungiamo semplicemente una terza riga all'interno di WHERE:
La riga ?item wdt:P26 ?dolcemetà è sempre una tripla che ha come terzo elelmento una variabile anziché un valore (P26 è la proprietà "coniuge").
A questo punto potrebbe essere utile anche vedere nei risultati chi sono questi coniugi. Per farlo dobbiamo intervenire sulla riga con SELECT (che è quella in cui esplicitiamo quali colonne vogliamo far comparire nei risultati). Inseriamo seplicemente ?dolcemetà (la stessa variabile inserita nel WHERE) se vogliamo l'elenco degli identificativi Q, oppure ?dolcemetàLabel se vogliamo le etichette (possiamo anche iserirli entrambi, come nell'esempio sotto).
Se invece volessimo cercare tutti i poeti italiani sposati con poeti, dovremmo aggiungere una nuova riga. Questa nuova riga non inizierà più con ?item, ma con ?dolcemetà, perché stiamo ricercando una variabile non più sui poeti italiani, ma sui loro coniugi:
E se questi coniugi volessimo vederli in faccia? Beh, possiamo chiedere di mostrare, quando esistenti, le immagini dei couniugi dei nostri poeti italiani. Qui entra in gioco la nuova keyword OPTIONAL, dicenogli che per ?dolcemetà vogliamo che venga mostrato il valore ?image (qualunque esso sia) per la proprietà P18 (immagine). D notare che ?image va riportato anche nella riga con SELECT per poter vedere l'immagine tra i risultati.
OPTIONAL non va a cercare solo gli elementi che rispettano una specifica condizione, ma ti mostra la condizione se un elemento la rispetta. Se invece volessimo vedere le foto dei poeti italiani (quindi non dei loro coniugi), al posto di dolcemetà dovremmo scrivere ?item.
Adesso vediamo i nomi dei file immagine, ma se volessimo vedere direttamente le immagini in una galleria sarebbe sufficiente passare dalla vista "Table" alla vista "Image grid" direttamente nel query service.
- Contenuti extra non raccontati da Asaf
I risultati di default vengono visualizzati sotto forma di tabella. Noi possiamo cambiare visualizzazione con il menù a tendina nel query service, ma possiamo anche impostare il tipo di visualizzazione direttamente nella query tramite la parola magica #defaultView:
Prendendo l'esempio di prima, aggiungendo #defaultView:ImageGrid alla query, i risultati ci saranno mostrati direttamente come galleria di immagini:
I valori consentiti per questa parola magica sono:
Galleria d'immagini | #defaultView:ImageGrid |
Mappa | #defaultView:Map |
Grafico a linee | #defaultView:LineChart |
Grafico a barre | #defaultView:BarChart |
Grafico ad aree | #defaultView:AreaChard |
Grafo ad albero | #defaultView:Tree |
Linea temporale | #defaultView:Timeline |
Pallogramma | #defaultView:BubbleChart |
Abbiamo visto come ricercare, ad esempio, tra gli elementi che sono istanza di qualcosa (per esempio, ?item wdt:P106 wd:Q49757 per cercare i poeti con cittadinanza italiana). Ma se volessimo fare una ricerca più ampia, comprendendo non solo i poeti, ma tutti gli scrittori? Dovremmo semplicemente modificare la query di sinistra per farla diventare quella di destra, sostituendo la riga ?item wdt:P106 wd:Q49757 con ?item wdt:P106/wdt:P279* wd:Q36180 per ricercare tra le persone che hanno come occupazione (P106) il valore "scrittore" (Q36180) o una sottoclasse (P279) di scrittore: quindi, oltre agli scrittori, i poeti, gli sceneggiatori, i drammaturghi, i romanzieri, i favolisti, i librettisti, eccetera.
SELECT ?item ?itemLabel
WHERE {
?item wdt:P106 wd:Q49757. #tutti i poeti
?item wdt:P27 wd:Q38. #tutti i cittadini italiani
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
} |
SELECT ?item ?itemLabel
WHERE {
?item wdt:P106/wdt:P279* wd:Q36180. #tutti gli scrittori (e sottoclasse di scrittore)
?item wdt:P27 wd:Q38. #tutti i cittadini italiani
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
} |