Search code examples
sparqldbpedia

dbpedia's snorql sparql sorting by the last character


I want to sort the ?Artis by its last character. I tried to just do order by, but the result is sorted by its first character.

PREFIX onto: <http://dbpedia.org/ontology/>
PREFIX xs: <http://www.w3.org/2001/XMLSchema#>

SELECT * WHERE {
 ?Artis onto:birthDate ?Tanggal_Lahir . 
 FILTER (?Tanggal_Lahir= "1990-01-05"^^xs:date)
} ORDER BY DESC (?Artis) LIMIT 10

Solution

  • Since SPARQL 1.1, you can use BIND to bind values to variables. The rest is just a matter of string hacks, e.g. replacement + regex like in this example:

    replace(strafter(str(?Artis), str(dbr:))
    

    converts the IRI http://dbpedia.org/resource/Some_Example to the string Some_Example

    Then

    replace(strafter(str(?Artis), str(dbr:)), ".*(.)$", "$1") as ?lastChar)
    

    picks the last char via a regex, $1 represents the group in the regex.

    The final query would be

    PREFIX dbo: <http://dbpedia.org/ontology/>
    PREFIX dbr: <http://dbpedia.org/resource/>
    PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
    
    SELECT * WHERE {
     ?Artis dbo:birthDate ?Tanggal_Lahir . 
     FILTER (?Tanggal_Lahir = "1990-01-05"^^xsd:date)
     BIND(replace(strafter(str(?Artis), str(dbr:)), ".*(.)$", "$1") as ?lastChar)
    } 
    ORDER BY DESC (?lastChar) 
    LIMIT 10
    

    Result (sample):

    +------------------------------------------------------+---------------+----------+
    |                        Artis                         | Tanggal_Lahir | lastChar |
    +------------------------------------------------------+---------------+----------+
    | http://dbpedia.org/resource/Barış_Memiş              | 1990-01-05    | ş        |
    | http://dbpedia.org/resource/Asha_Roy                 | 1990-01-05    | y        |
    | http://dbpedia.org/resource/Gaurav_Pandey            | 1990-01-05    | y        |
    | http://dbpedia.org/resource/Eldar_Ragib_Ogly_Mamedov | 1990-01-05 v  |          |
    | http://dbpedia.org/resource/Akeem_Thomas             | 1990-01-05    | s        |
    | ...                                                  | ...           | ...      |
    +------------------------------------------------------+---------------+----------+
    

    Note, this indeed also picks a char like ) the result value, e.g. for the resource http://dbpedia.org/resource/Stephen_Stirling_(footballer) the result will be

    +-----------------------------------------------------------+-------------+---+
    | http://dbpedia.org/resource/Stephen_Stirling_(footballer) | 1990-01-05  | ) |
    +-----------------------------------------------------------+-------------+---+
    

    In addition, this only works for DBpedia resources beginning with the namespace http://dbpedia.org/resource/. For arbitrary datasets, omit the strafter part and just use the given regex.

    As a side note, it would be good if you stick to common namespace declarations, e.g. dbo instead of onto and xsd instead of xs.