lvaudor / glitter

an R package which writes SPARQL queries
https://lvaudor.github.io/glitter
43 stars 4 forks source link

How to do a query with timePrecision #91

Open spinza opened 1 year ago

spinza commented 1 year ago

Not sure how to create this query in glitter:

SELECT ?item ?itemLabel ?time ?precision
WHERE
{
  ?item p:P569/psv:P569 [wikibase:timePrecision ?precision; wikibase:timeValue ?time].
  FILTER (   YEAR(?time) = 1700 ).
  SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" }
} 
LIMIT 10

This above works with the query service.

I have this:

library(tidyverse)
library(glitter)

query <- spq_init() %>%
  spq_add("?item p:P569/psv:P569 [wikibase:timePrecision ?precision; wikibase:timeValue ?time]") %>% 
  spq_filter(year(time)==1700) %>% 
  spq_head(10)
#> Error in `purrr::map_chr()`:
#> ℹ In index: 2.
#> Caused by error:
#> ! Result must be length 1, not 2.

#> Backtrace:
#>      ▆
#>   1. ├─... %>% spq_head(10)
#>   2. ├─glitter::spq_head(., 10)
#>   3. ├─glitter::spq_filter(., year(time) == 1700)
#>   4. ├─glitter::spq_add(., "?item p:P569/psv:P569 [wikibase:timePrecision ?precision; wikibase:timeValue ?time]")
#>   5. │ ├─... %>% unique()
#>   6. │ └─purrr::map_chr(unname(elts), keep_prefix)
#>   7. │   └─purrr:::map_("character", .x, .f, ..., .progress = .progress)
#>   8. │     ├─purrr:::with_indexed_errors(...)
#>   9. │     │ └─base::withCallingHandlers(...)
#>  10. │     └─purrr:::call_with_cleanup(...)
#>  11. ├─base::unique(.)
#>  12. ├─stats::na.omit(.)
#>  13. └─base::.handleSimpleError(...)
#>  14.   └─purrr (local) h(simpleError(msg, call))
#>  15.     └─cli::cli_abort(...)
#>  16.       └─rlang::abort(...)

Created on 2023-01-30 with reprex v2.0.2

lvaudor commented 1 year ago

Reformulated in SPARQL without the relative clauses, your query would be:

SELECT ?item ?itemLabel ?time ?precision
WHERE
{
  ?item p:P569 ?r.
  ?r psv:P569 ?birth.
  ?birth wikibase:timePrecision ?precision.
  ?birth wikibase:timeValue ?time.
  FILTER (   YEAR(?time) = 1700 ).
  SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" }
} 
LIMIT 10

Hence you could pass it through glitter commands with:

spq_init() %>% 
  spq_add("?item p:P569 ?r") %>% 
  spq_add("?r psv:P569 ?birth") %>% 
  spq_add("?birth wikibase:timePrecision ?precision") %>% 
  spq_add("?birth wikibase:timeValue ?time") %>% 
  spq_filter(year(time)==1700) %>% 
  spq_head(10) %>% 
  spq_perform()

(I have just added the psv prefix to the list of "usual" prefixes)

I find the use of qualifiers to statements quite difficult to grasp though (difficult to understand and formulate in SPARQL, and no attempt to simplify this has been made so far in glitter). We might try and find ways to make this easier or at the very least include more examples with such qualifiers...

Thanks for your feedback anyway!

lvaudor commented 1 year ago

It's actually quite important that we add a few examples of triple patterns of the kind "statement qualifiers"... Like: We query the population of a city, but also get the date of that census data. Or: We get the release date of a movie, but also get the country which that date of release corresponds to. Or: We get the people that were ministre de la Transition écologique et solidaire but with starting and ending dates of exercise:

ministres <- spq_init() %>%
  spq_add("?person p:P39 ?statement",.label="?person") %>% 
  spq_add("?statement ps:P39 wd:Q29962937") %>% 
  spq_add("?statement pq:P580 ?start") %>% 
  spq_add("?statement pq:P582 ?end") %>% 
  spq_select(-statement) %>% 
  spq_perform()

Maybe adding a little drawing to explain how statement qualifiers work would be good because the logic is not obvious. The reference to the statement is put in the triple pattern as if it was an object... Hopefully such a graph/drawing would be eventually added to the sequins package but we can just think or produce this graph "by hand" to include in the glitter documentation...

OR maybe we could modify the syntax of triple patterns to make all this easier? i.e. make it possible to do something like:

ministres <- spq_init() %>%
  spq_add("?person wdt:P39 wd:Q29962937",.label="?person", .backreference="?statement") %>% 
  spq_add("?statement wdt:P580 ?start") %>% 
  spq_add("?statement wdt:P582 ?end") %>% 
  spq_select(-statement) %>% 
  spq_perform()

@maelle what do you think? I'd find it a lot easier to understand (and again, it is actually quite often that users will need to use statement qualifiers) but it might be a hassle to make that possible...

maelle commented 1 year ago

I actually find

ministres <- spq_init() %>%
  spq_add("?person p:P39 ?statement",.label="?person") %>% 
  spq_add("?statement ps:P39 wd:Q29962937") %>% 
  spq_add("?statement pq:P580 ?start") %>% 
  spq_add("?statement pq:P582 ?end") %>% 
  spq_select(-statement) %>% 
  spq_perform()

easier to understand.