2

Is there an RDF data/other format that allow me to get all the properties that can exist in a category e.g. Person, then I should be returned properties like sex, date of birth.

How to query this information at https://query.wikidata.org/ ?

What I want is this https://www.wikidata.org/wiki/Wikidata:List_of_properties/Summary_table But is there a better format for this? I want to access programmatically.

UPDATE

This query is too heavy, causes timeout.

SELECT ?p ?attName  WHERE {
          ?q wdt:P31 wd:Q5.
          ?q ?p ?statement.
          ?realAtt wikibase:claim ?p.
          ?realAtt rdfs:label ?attName.
          FILTER(((LANG(?attName)) = "en") || ((LANG(?attName)) = ""))
    }
    GROUP BY ?p ?attName

I must specify the entity, e.g. to Barrack Obama then it works, but this does not give me the all possible properties.

SELECT ?p ?attName  WHERE {
      BIND(wd:Q76 AS ?q)
      ?q wdt:P31 wd:Q5.
      ?q ?p ?statement.
      ?realAtt wikibase:claim ?p.
      ?realAtt rdfs:label ?attName.
      FILTER(((LANG(?attName)) = "en") || ((LANG(?attName)) = ""))
}
GROUP BY ?p ?attName
logi-kal
  • 7,107
  • 6
  • 31
  • 43
William
  • 5,526
  • 6
  • 20
  • 42
  • Why can't you use a SPARQL query like `SELECT DISTINCT ?p {?s rdf:type/rdfs:subClassOf* ; ?p ?o }` ? – UninformedUser Apr 17 '18 at 05:49
  • @AKSW Hi, I interpret that into the real example as `SELECT DISTINCT ?p {?s wdt:P31 wd:Q5 ; ?p ?o }` anything that is instance of human , but that query is so resource intensive that it cause "Query timeout limit reached" , because it's getting all the instance of human. – William Apr 17 '18 at 06:16
  • 1
    I know that this query is expensive. An alternative though incomplete way would a) reduce it to some smaller subclass (if possible) or b) check for properties whose domain is person (or one of it's subclasses) – UninformedUser Apr 17 '18 at 06:41
  • a) not possible, because human is subclass enough. b) it may work for person category, but not for other category like planet, it has data from many different property class. so a lot of information is lost. I think my temporary solution will be to specify a specific instance (last query at my updated question) – William Apr 17 '18 at 07:04
  • Well, you could at least restrict it to `n` number of instances which you get in a sub-query. This could at least return some more properties, though, still no completeness guarantee – UninformedUser Apr 17 '18 at 09:25

1 Answers1

4

1

The page you have linked to is created by a bot. Contact the BetaBot operator, if you need to know how the bot works.

2

Perhaps the bot relies on the wd:P1963 property:

SELECT ?property ?propertyLabel {
  VALUES (?class) {(wd:Q5)}
  ?class wdt:P1963 ?property
  SERVICE wikibase:label { bd:serviceParam wikibase:language "en" }   
} ORDER BY ASC(xsd:integer(strafter(str(?property), concat(str(wd:), "P"))))

The above query returns 49 results.

3

I'd suggest you rely on type constraints from property pages:

SELECT ?property ?propertyLabel {
  VALUES (?class) {(wd:Q5)}
  ?property a wikibase:Property .
  ?property p:P2302 [ ps:P2302 wd:Q21503250 ; 
                      pq:P2309 wd:Q21503252 ; 
                      pq:P2308 ?class ] .
  SERVICE wikibase:label { bd:serviceParam wikibase:language "en" }   
} ORDER BY ASC(xsd:integer(strafter(str(?property), concat(str(wd:), "P"))))

The above query returns 700 results.

4

The first query from your question works fine for relatively small classes, e. g. wd:Q6256 ('country'). On the public endpoint, it is not possible to make the query work for large classes.

However, you could split the query into small parts. In Python:

from wdqs import Client
from time import sleep

client = Client()
result = client.query("SELECT (count(?p) AS ?c) {?p a wikibase:Property}")

count = int(result[0]["c"])
offset = 0
limit = 50
possible = []

while offset <= count:
    props = client.query("""
        SELECT ?property  WHERE { 
            hint:Query hint:optimizer "None" .
            {
              SELECT ?property {
                  ?property a wikibase:Property .
              } ORDER BY ?property OFFSET %s LIMIT %s
            }
            ?property wikibase:directClaim ?wdt.
            FILTER EXISTS {
                ?human ?wdt [] ; wdt:P31 wd:Q5 .
                hint:Group hint:maxParallel 501 .   
            }
            hint:Query hint:filterExists "SubQueryLimitOne" .
            # SERVICE wikibase:label { bd:serviceParam wikibase:language "en" }
        } 
        """ % (offset, limit))

    for prop in props:
        possible.append(prop['property'])
    offset += limit
    print (len(possible), min(offset, count))
    sleep(0.25)

The last line of the output is:

2156 5154

Stanislav Kralin
  • 11,070
  • 4
  • 35
  • 58
  • 1
    Hi, Thanks I tried, it seem okay for "human" class, but for other class I lost some property still like Q43229 (Organization), it doesn't give me the P571 (inception) , this property does not have type constraint. – William Apr 17 '18 at 16:45
  • Hey, thank you very much, sorry that I wasn't active in this site last few days. I will look later. Thanks – William Apr 27 '18 at 16:12
  • @William, OK. `wdqs` is here: https://github.com/yuvipanda/python-wdqs. Previous revision of the answer contains code that uses SPARQLWrapper instead. Probably you can use concurrent requests: Wikidata [allows](https://stackoverflow.com/a/42590757/7879193) up to 5 simultaneous requests from one IP. – Stanislav Kralin Apr 28 '18 at 08:21