Search code examples
propertiesquery-optimizationsparqlunionwikidata

Retrieve properties and their descriptions from instances of the same class


I want to retrieve all distinct object properties of instances with the same type (class), starting with two initial seeds (wd:Q963 and wd:Q42320). First, I ask for the type (and maybe subtype) of such seeds. Second, all instances of the same class of the seeds are retrieved. Third, properties of the instances are retrieved. Finally, I want to retrieve descriptions of such properties and if possible alternative labels. My query is as follows:

select distinct ?property ?description ?label where{
  {     
    wd:Q963 wdt:P31 ?typesSubject . 
    ?instancesS (wdt:P31|wdt:P279) ?typesSubject .
    ?instancesS ?property ?unknown .
  }
 UNION
  { 
    wd:Q42320 wdt:P31 ?typesObject . 
    ?instancesO (wdt:P31|wdt:P279) ?typesObject . 
    ?unknown ?property ?instancesO . 
  }

 ?claimPredicate wikibase:directClaim ?property . 
 ?claimPredicate schema:description ?description .  
 ?claimPredicate rdfs:label ?label .  

   FILTER(strstarts(str(?property),str(wdt:)))
   FILTER(strstarts(str(?unknown),str(wd:)))

   FILTER(LANG(?description) = "en").  
   FILTER(LANG(?label) = "en"). 

}

The problem is that my actual query takes a lot of time and it fails in the public Wikidata endpoint. Does anyone can provide me some hints to optimize such a query?


Solution

  • To be honest, I can't understand the aim of your query. I suppose you are interested in semantic similarity or something like.

    Basically, you could reduce the number of joins, retrieving only unique wdt-predicates with nested SELECT DITINCT.

    SELECT ?property ?claimPredicateLabel ?claimPredicateDescription 
    WHERE {
      hint:Query hint:optimizer "None" .
      {  
      SELECT DISTINCT ?property {
        VALUES (?s) {(wd:Q963) (wd:Q42320)}
        ?s wdt:P31/^(wdt:P31|wdt:P279) ?instances .
        ?instances ?property ?unknown .
        }
      }
      ?claimPredicate wikibase:directClaim ?property . 
      SERVICE wikibase:label { bd:serviceParam wikibase:language "en" . }
    }
    

    Try it!

    This is fast enough (~ 3s) even with SERVICE wikibase:label.

    Also, you don't need FILTER(strstarts(str(?property),str(wdt:))) after ?claimPredicate wikibase:directClaim ?property.


    As for hint:Query hint:optimizer "None", this hint forces Blazegraph to follow standard bottom-up evaluation order. In this particular query, hint:Query hint:optimizer "Runtime" or hint:SubQuery hint:runOnce true should also work.