How to get all properties for only a specific category in Wikidata?

前端 未结 1 1564
隐瞒了意图╮
隐瞒了意图╮ 2021-01-15 11:30

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 bi

1条回答
  •  夕颜
    夕颜 (楼主)
    2021-01-15 12:13

    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

    0 讨论(0)
提交回复
热议问题