Projekt: Hesla Jednoty bratrské/výročí/2019/SPARQL
Tato stránka je součástí projektu: | |
Příslušnost: skupinová |
Projekt: Hesla Jednoty bratrské/výročí/2019/SPARQL – na této stránce se pokusíme dohledat nějaká výročí na Wikidatech pomocí Wikidata/SPARQL.
Známé události – různé defenestrace
[editovat]Začneme s tím, že:
- se podíváme na nějaké známé události, které jsme si už předtím vyhledali
- podíváme se, jaké záznamy na wikidatech jim přísluší
- pokusíme se dohledat tyto známé události nějakým skriptem
- pak se ten skript pokusíme nějak modifikovat, aby nám našel i to, co ještě neznáme
- d: Q688769 – Pražská defenestrace
wdt:P31 wd:Q220277 # instance čeho / defenestrace wdt:P361 wd:Q374696 # část čeho / Pražská defenestrace wdt:P585 1419-07-30 # datum
Dohledáme všechny defenestrace:
SELECT * WHERE {
?event wdt:P31 wd:Q220277 .
}
Ukaž! – Našlo jen dvě defenestrace.
SELECT ?event ?eventLabel WHERE {
?event wdt:P31 wd:Q220277 .
SERVICE wikibase:label { bd:serviceParam wikibase:language "cs, en". }
}
event | eventLabel |
---|---|
wd:Q688769 | Pražská defenestrace (1419) |
wd:Q13365740 | Pražská defenestrace (1613) |
Jsou to ty naše. Buď se jinde než v Praze nedefenestrovalo anebo je tam něco špatně na tom d:Q220277.
Zkusíme vyselektovat datum, ale nějak se nám to nedaří, podívám se tedy na d: Wikidata:SPARQL query service/queries/examples#Battles per year per country last 80 years a po inspiraci filtruju:
SELECT * WHERE {
?event wdt:P31 wd:Q220277 . # instance čeho / defenestrace
?event wdt:P585 ?date .
FILTER (YEAR(?date) = 1419)
}
event | date |
---|---|
wd:Q688769 | 8. srpen 1419 |
Některé události ale mohou trvat delší dobu, tak je nutno použít d:Property:P580 = počátek nějakého stavu a d:Property:P582 = konec nějakého stavu.
SELECT * WHERE {
?event wdt:P31 wd:Q220277 . # instance čeho / defenestrace
?event wdt:P585 ?date .
OPTIONAL {?event wdt:P580 ?d1} # počátek nějakého stavu
OPTIONAL {?event wdt:P585 ?d2} # datum
OPTIONAL {?event wdt:P582 ?d3} # konec nějakého stavu
BIND(IF(!BOUND(?d1),(IF(!BOUND(?d2),?d3,?d2)),?d1) as ?date)
BIND(YEAR(?date) as ?year)
FILTER (?year = 1419)
}
event | date | d1 | d2 | d3 | year |
---|---|---|---|---|---|
wd:Q688769 | 8. srpen 1419 | 8. srpen 1419 | 1419 |
- d: Q13365740 – Pražská defenestrace (1618)
wdt:P31 wd:Q220277 # instance čeho / defenestrace wdt:P361 wd:Q374696 # část čeho / Pražská defenestrace wdt:P585 23. 5. 1618gregoriánský # datum
Takže řádné zajímavé údaje ve srovnání s První pražskou tu nejsou, jen ta poznámka, že datum je už dle gregoriánského kalendáře.
Všechny události 1419
[editovat]Tak teď zkusíme události roku 1419:
SELECT * WHERE {
?event wdt:P585 ?date .
BIND(YEAR(?date) as ?year)
FILTER (?year = 1419)
}
Najde mi 14 událostí, mezi nimi i tu defenestraci d:Q688769.
Zkusím tedy do dotazu zahrnout i případy, kdy se jedná o nějaký proces s počátkem a koncem:
SELECT * WHERE {
OPTIONAL {?event wdt:P580 ?d1} # počátek nějakého stavu
OPTIONAL {?event wdt:P585 ?d2} # datum
OPTIONAL {?event wdt:P582 ?d3} # konec nějakého stavu
BIND(IF(!BOUND(?d1),(IF(!BOUND(?d2),?d3,?d2)),?d1) as ?date)
BIND(YEAR(?date) as ?year)
FILTER (?year = 1419)
}
To mi našlo ale jen 4 události, v žádné není ?d2.
Tak je asi někde nějaká chyba, koukám na d:Wikidata:SPARQL tutorial#BIND, BOUND, IF
Zkusím to strukturovat:
SELECT * WHERE {
OPTIONAL {?event wdt:P580 ?d1} # počátek nějakého stavu
OPTIONAL {?event wdt:P585 ?d2} # datum
OPTIONAL {?event wdt:P582 ?d3} # konec nějakého stavu
BIND(IF(!BOUND(?d1), # condition: pokud není ?d1
(IF(!BOUND(?d2), # pak tedy condition: pokud není ani ?d2
?d3,?d2)), # tak tedy ?d3, jinak ?d2
?d1) # jinak tedy ?d1
as ?date)
BIND(YEAR(?date) as ?year)
FILTER (?year = 1419)
}
No si myslím, že by se mělo vycházet z toho ?d2, a pokud není, tak ty další ?d1 a ?d3, ale tuším, že to nakonec vyjde nastejno:
SELECT * WHERE {
OPTIONAL {?event wdt:P580 ?d1} # počátek nějakého stavu
OPTIONAL {?event wdt:P585 ?d2} # datum
OPTIONAL {?event wdt:P582 ?d3} # konec nějakého stavu
BIND(IF(!BOUND(?d2), # condition: pokud není ?d2
(IF(!BOUND(?d1), # pak tedy condition: pokud není ani ?d2
?d3,?d1)), # tak tedy ?d3, jinak ?d2
?d2) # jinak tedy ?d2
as ?date)
BIND(YEAR(?date) as ?year)
FILTER (?year = 1419)
}
Ano, tušil jsem správně, vyšlo to nastejno. Možná nejdřív musím zkusit najít ?d2 bez toho option, s tečkou na konci?? Ale moc by mi to nedávalo smysl
SELECT * WHERE {
?event wdt:P585 ?d2 .
OPTIONAL {?event wdt:P580 ?d1} # počátek nějakého stavu
OPTIONAL {?event wdt:P585 ?d2} # datum
OPTIONAL {?event wdt:P582 ?d3} # konec nějakého stavu
BIND(IF(!BOUND(?d2), # condition: pokud není ?d2
(IF(!BOUND(?d1), # pak tedy condition: pokud není ani ?d2
?d3,?d1)), # tak tedy ?d3, jinak ?d2
?d2) # jinak tedy ?d2
as ?date)
BIND(YEAR(?date) as ?year)
FILTER (?year = 1419)
}
No jo, dopadlo to, jak jsem předpokládal, našlo mi to všechno, kde je ?d2, ale ty s ?d1 a ?d3 už to nenašlo.
Momentálně nevím, co s tím, vznáším dotaz na FB do skupiny Wikidata CS.
No, zkusím se ještě podívat, co je to za těch 14 událostí:
SELECT ?date ?event ?eventLabel ?d1 ?d2 ?d3 WHERE {
?event wdt:P585 ?d2 .
OPTIONAL {?event wdt:P580 ?d1} # počátek nějakého stavu
OPTIONAL {?event wdt:P585 ?d2} # datum
OPTIONAL {?event wdt:P582 ?d3} # konec nějakého stavu
BIND(IF(!BOUND(?d2), # condition: pokud není ?d2
(IF(!BOUND(?d1), # pak tedy condition: pokud není ani ?d2
?d3,?d1)), # tak tedy ?d3, jinak ?d1
?d2) # jinak tedy ?d2
as ?date)
BIND(YEAR(?date) as ?year)
FILTER (?year = 1419)
SERVICE wikibase:label { bd:serviceParam wikibase:language "cs, en". }
}
Dotaz běží, běží a furt nic...
Vypršel časový limit pro dotaz
No konečně to vyjelo. Ale nevím, jak si to přebrat :-(
Mezitím mi d:User:Matěj Suchánek na FB odpověděl, že by se to dalo dělat přes sjednocení (UNION), toto je jeho řešení:
SELECT ?event ?eventLabel ?eventDescription ?year ?date WHERE {
{
?event wdt:P585 ?date .
} UNION {
?event wdt:P580 ?date .
} UNION {
?event wdt:P582 ?date .
} .
BIND( YEAR( ?date ) AS ?year ) .
FILTER( ?year = 1419 ) .
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" } .
}
Tak to mi vyhodilo 20 odpovědí.
Další příklad nacházím přímo mezi příklady na Wikidata Query d: Wikidata:SPARQL_query_service/queries/examples#Recent Events:
#Recent Events
SELECT ?event ?eventLabel ?date
WHERE
{
# find events
?event wdt:P31/wdt:P279* wd:Q1190554.
# with a point in time or start date
OPTIONAL { ?event wdt:P585 ?date. }
OPTIONAL { ?event wdt:P580 ?date. }
# but at least one of those
FILTER(BOUND(?date) && DATATYPE(?date) = xsd:dateTime).
# not in the future, and not more than 31 days ago
BIND(NOW() - ?date AS ?distance).
FILTER(0 <= ?distance && ?distance < 31).
# and get a label as well
OPTIONAL {
?event rdfs:label ?eventLabel.
FILTER(LANG(?eventLabel) = "en").
}
}
# limit to 10 results so we don't timeout
LIMIT 10
Tak si to trochu upravíme:
#Events in the year 1419
SELECT ?event ?eventLabel ?date
WHERE
{
# find events
?event wdt:P31/wdt:P279* wd:Q1190554. # instance čeho / nadtřída | událost
# with a point in time or start date
OPTIONAL { ?event wdt:P585 ?date. } # datum (datum události)
OPTIONAL { ?event wdt:P580 ?date. } # od (počátek nějakého stavu)
# but at least one of those
FILTER(BOUND(?date) && DATATYPE(?date) = xsd:dateTime). # http://www.datypic.com/sc/xsd/t-xsd_dateTime.html http://books.xmlschemata.org/relaxng/ch19-77049.html
# year 1419
FILTER(YEAR(?date) = 1419) .
# and get a label as well
OPTIONAL {
?event rdfs:label ?eventLabel.
FILTER(LANG(?eventLabel) = "en").
}
}
# limit to 20 results so we don't timeout
LIMIT 20
I tak to trvá hrozně dlouho, nakonec:
Vypršel časový limit pro dotaz
Ani s LIMIT 5 se ničeho nedočkám. Nejspíš za to může ta konstrukce:
?event wdt:P31/wdt:P279* wd:Q1190554.
A jak potvrzuje d:User:Matěj Suchánek na FB, asi se v tom nemýlím. Zkusím zakomentovat tu hvězdičkovou konstrukci:
#Events in the year 1419
SELECT ?event ?eventLabel ?date
WHERE
{
# find events
# ?event wdt:P31/wdt:P279* wd:Q1190554. # instance čeho / nadtřída | událost
# with a point in time or start date
OPTIONAL { ?event wdt:P585 ?date. } # datum (datum události)
OPTIONAL { ?event wdt:P580 ?date. } # od (počátek nějakého stavu)
# but at least one of those
FILTER(BOUND(?date) && DATATYPE(?date) = xsd:dateTime). # http://www.datypic.com/sc/xsd/t-xsd_dateTime.html http://books.xmlschemata.org/relaxng/ch19-77049.html
# year 1419
FILTER(YEAR(?date) = 1419) .
# and get a label as well
OPTIONAL {
?event rdfs:label ?eventLabel.
FILTER(LANG(?eventLabel) = "en").
}
}
LIMIT 20
A hned dostanu 20 výsledků: Ukaž!
Ale pokud tam ten LIMIT nedám (zakomentuju), dostanu jen 14 výsledků. To fakt nechápu:
#Events in the year 1419
SELECT ?event ?eventLabel ?date
WHERE
{
# find events
# ?event wdt:P31/wdt:P279* wd:Q1190554. # instance čeho / nadtřída | událost
# with a point in time or start date
OPTIONAL { ?event wdt:P585 ?date. } # datum (datum události)
OPTIONAL { ?event wdt:P580 ?date. } # od (počátek nějakého stavu)
# but at least one of those
FILTER(BOUND(?date) && DATATYPE(?date) = xsd:dateTime). # http://www.datypic.com/sc/xsd/t-xsd_dateTime.html http://books.xmlschemata.org/relaxng/ch19-77049.html
# year 1419
FILTER(YEAR(?date) = 1419) .
# and get a label as well
OPTIONAL {
?event rdfs:label ?eventLabel.
FILTER(LANG(?eventLabel) = "en").
}
}
# LIMIT 20
Tak ještě zkouším další příklad: d: Wikidata:SPARQL query service/queries/examples/cs#Locations of battles
#added before 2016-10
#defaultView:Map
SELECT ?label ?coord ?subj ?year
WHERE
{
?subj wdt:P31 wd:Q178561 .
?subj wdt:P625 ?coord .
OPTIONAL {?subj wdt:P580 ?d1}
OPTIONAL {?subj wdt:P585 ?d2}
OPTIONAL {?subj wdt:P582 ?d3}
BIND(IF(!BOUND(?d1),(IF(!BOUND(?d2),?d3,?d2)),?d1) as ?date)
BIND(YEAR(?date) as ?year)
?subj rdfs:label ?label filter (lang(?label) = "en")
}
A tady nacházím z roku 1419 např.:
- d: Q1468732 – bitva pod Vyšehradem – předtím nalezena
- d: Q11156922 – bitva u Živohoště – předtím nalezena
- d: Q513007 – bitva u Záblatí (poblíž Prachatic) – předtím nenalezena. Jak to?
Jen se ještě divím, že:
- d: Q3493159 – bitva u Kutné Hory
se zobrazuje někde na hranicích s Rakouskem u Nové Bystřice. Asi by to chtělo něco opravit.