1

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?

Stanislav Kralin
  • 11,070
  • 4
  • 35
  • 58
  • 1
    Retrieval of the `407` properties works in ~ 3s: `select distinct ?property where{ { ?instancesS (wdt:P31|wdt:P279)/^wdt:P31 wd:Q963 . ?instancesS ?property ?unknown . FILTER(strstarts(str(?property),str(wdt:))) } UNION { ?instancesO (wdt:P31|wdt:P279)/^wdt:P31 wd:Q42320 . ?unknown ?property ?instancesO . FILTER(strstarts(str(?unknown),str(wd:))) } }` the problem is the join with the claims – UninformedUser Mar 22 '18 at 07:24
  • thank you @AKSW, you are right, I did not know how to address such join issue – José Martínez Mar 22 '18 at 21:31

1 Answers1

2

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.

Stanislav Kralin
  • 11,070
  • 4
  • 35
  • 58
  • 1
    Thank you very much @Stanislav, Query hints helped a lot. Additionally, I also included the instruction `(GROUP_CONCAT(?alternative;separator="|") as ?altLabel)` together with `?claimPredicate skos:altLabel ?alternative .` and a `group by` in order to obtain all possible alternative labels of every property in the same row – José Martínez Mar 22 '18 at 21:26