Search code examples
sparqlwikidata-query-service

Access the property of a property


I have the following query, that I ran on the wikidata query service web interface:

SELECT ?objectLabel ?mass
WHERE {
  ?object wdt:P397 wd:Q525.  # the object should have the sun as parent astronomical body
  ?object wdt:P31 ?status.
  ?object wdt:P2067 ?mass.

  # Here are the accepted object status
  VALUES ?status {wd:Q128207 wd:Q121750 wd:Q1319599}.  # terrestrial planet, gas giant, ice giant

  # automatically use the english label for ?xLabel variables 
  SERVICE wikibase:label { bd:serviceParam wikibase:language "en" }
} 

I found that the mass value is given in a specific unit, yottagram in case of the Earth. How can I access this information ?

I tried to add something like:

?mass   wdt:P2237 ?mass_unit.

But, expectedly, this doesn't work because ?mass is an integer, not an object referencing the Earth mass. Using the property itself as a subject doesn't work neither:

?object wdt:P2067 ?mass.
wd:P2067 wdt:P2237 ?massUnit.

This returns all tuples with all available units. (Earth is associated with 5972.37 kilograms, 5972.37 yottagrams, 5972.37 solar mass, etc)

Also, chaining the properties leads to no results:

?object wdt:P2067/wdt:P2237 ?massUnit.

I imagine that I need to use, not the property itself, but an instance of it linking specifically the Earth and the integer that describes its mass.

How access the unit information ? (in case of Earth, Yottagram)


Solution

  • How Wikidata is represented in RDF (and thus in SPARQL) is described at MediaWiki.org page Wikibase/Indexing/RDF Dump Format.

    The relevant part is that, in your case, wdt:P2067 directly gives you just the value, but if you instead use p:P2067, you get the whole statement. From there, you can use psv:P2067 to get a value node. And from there, you can use wikibase:quantityAmount to get the mass (just like you could with wdt:P2067), but you can also use wikibase:quantityUnit to get the entity representing the unit.

    So, the whole query could look like this:

    SELECT ?objectLabel ?mass ?massUnitLabel
    WHERE {
      ?object wdt:P397 wd:Q525.  # the object should have the sun as parent astronomical body
      ?object wdt:P31 ?status.
    
      ?object p:P2067/psv:P2067 ?massValue.
      ?massValue wikibase:quantityAmount ?mass.
      ?massValue wikibase:quantityUnit ?massUnit.
    
      # Here are the accepted object status
      VALUES ?status {wd:Q128207 wd:Q121750 wd:Q1319599}.  # terrestrial planet, gas giant, ice giant
    
      # automatically use the english label for ?xLabel variables 
      SERVICE wikibase:label { bd:serviceParam wikibase:language "en" }
    }
    

    If you wanted, you could eliminate the ?massValue variable by using the following code:

    ?object p:P2067/psv:P2067 [
      wikibase:quantityAmount ?mass;
      wikibase:quantityUnit ?massUnit ]