1

Consider the following extract from the GeoNames database :

@prefix gn:    <http://www.geonames.org/ontology#> .
@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .

<http://sws.geonames.org/690791/>
        a                        gn:Feature ;
        gn:featureClass          gn:A ;
        gn:featureCode           gn:A.PCLI ;
        gn:alternateName         "Україна"@uk , "ܐܘܟܪܢܝܐ"@arc ,  "Ուկրաինա"@hy , "ウクライナ"@ja , "Úkraína"@is;
        gn:name                  "Ukraine" ;
        gn:officialName          "Ucraína"@gl , "Ukraine"@fr , "U-crai-na (Ukraine)"@vi , "ཡུ་ཀརེན།"@bo.

So, I'm trying to get the name in a specif language, for example fr and if it's not available fall back to the default. Moreover, this name can come from any of the three predicates: gn:alternateName , gn:name and gn:officialName.

So for example, for this sample, I expect to recover

----------------
| name         |
================
| "Ukraine"@fr |
----------------

But with my current solution :

PREFIX gn:        <http://www.geonames.org/ontology#>
PREFIX rdfs:      <http://www.w3.org/2000/01/rdf-schema#>

SELECT DISTINCT ?name
WHERE {
    values ?nameBearing { gn:name gn:alternateName gn:officialName}
    values ?countryfc { gn:A.PCLI gn:A.PCLD gn:A.PCLIX }
    ?loc    gn:featureCode      ?countryfc;

    OPTIONAL
    {
        ?loc    ?nameBearing        ?nameFR
        FILTER(langMatches(lang(?nameFR), "fr"))
    }

    OPTIONAL
    {
        ?loc    ?nameBearing        ?nameOTHER
        FILTER(langMatches(lang(?nameOTHER), ""))
    }

    BIND(COALESCE(?nameFR, ?nameOTHER) AS ?name)
}

I get

----------------
| name         |
================
| "Ukraine"    |
|              |
| "Ukraine"@fr |
----------------

probably because the way multiple values for a predicate is evaluated in SPARQL.

So is there any way to "group by ?loc" and get only values in one language?

gustavo-vm
  • 131
  • 2
  • 10
  • Do you want to know exactly what language it is in or you don't as long as it is either? What I mean is that you have separated `?nameFR` from `?nameOther` and if this is what you want or `?name` would do? – Artemis Jun 03 '15 at 15:30
  • No, I don't need to know the language, but I do need to get the French name whenever it's avaliable – gustavo-vm Jun 03 '15 at 23:15

1 Answers1

1

You can start with a query like this that finds name values and partitions them into French names and default (i.e., non-French) names:

prefix gn:    <http://www.geonames.org/ontology#>
prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#>

select ?s ?name ?frenchName ?defaultName where {
  values ?name { gn:alternateName gn:name gn:officialName }
  ?s ?name ?name_
  bind(if(langMatches(lang(?name_),"fr"),?name_,?undef) as ?frenchName)
  bind(if(langMatches(lang(?name_),"fr"),?undef,?name_) as ?defaultName)
}
--------------------------------------------------------------------------------------------------
| s                                 | name             | frenchName   | defaultName              |
==================================================================================================
| <http://sws.geonames.org/690791/> | gn:alternateName |              | "Úkraína"@is             |
| <http://sws.geonames.org/690791/> | gn:alternateName |              | "ウクライナ"@ja               |
| <http://sws.geonames.org/690791/> | gn:alternateName |              | "Ուկրաինա"@hy            |
| <http://sws.geonames.org/690791/> | gn:alternateName |              | "ܐܘܟܪܢܝܐ"@arc            |
| <http://sws.geonames.org/690791/> | gn:alternateName |              | "Україна"@uk             |
| <http://sws.geonames.org/690791/> | gn:name          |              | "Ukraine"                |
| <http://sws.geonames.org/690791/> | gn:officialName  |              | "ཡུ་ཀརེན།"@bo            |
| <http://sws.geonames.org/690791/> | gn:officialName  |              | "U-crai-na (Ukraine)"@vi |
| <http://sws.geonames.org/690791/> | gn:officialName  | "Ukraine"@fr |                          |
| <http://sws.geonames.org/690791/> | gn:officialName  |              | "Ucraína"@gl             |
--------------------------------------------------------------------------------------------------

That's a start, but sample and coalesce don't seem to work the way we'd want here. E.g., we can't do coalesce(sample(?frenchName),sample(?defaultName)) to get a single name.

Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353