retrieve list of mathematics categories from dbpedia? - sparql

Is there a way using SPARQL to retrieve all topics of in dpbedia?
http://dbpedia.org/snorql/
That is to say is there a way to extract all the subfields of the topics listed here:
http://en.wikipedia.org/wiki/Lists_of_mathematics_topics
The broad topics are lists here: http://dbpedia.org/page/Category:Fields_of_mathematics
I would like a list which shows the parent class and its subfield.

question 1:
depends on how you define topic....
you can query for instance for skos:Concept:
SELECT ?con
WHERE {
?con a skos:Concept
}
limit 1000
see result
question 2:
you can query for skos:broader properties, like:
SELECT ?parent (?label as ?sub)
WHERE {
{
?sub skos:broader <http://dbpedia.org/resource/Category:Fields_of_mathematics> .
?sub rdfs:label ?label .
} UNION {
<http://dbpedia.org/resource/Category:Fields_of_mathematics> rdfs:label ?parent
}
}
see results
retrieve a list of the next level of sub-fields of the above fields with:
SELECT ?parent ?sub ?subsub
WHERE {
{
?sub skos:broader <http://dbpedia.org/resource/Category:Fields_of_mathematics> .
OPTIONAL {?subsub dcterms:subject ?sub}
} UNION {
<http://dbpedia.org/resource/Category:Fields_of_mathematics> rdfs:label ?parent
}
}
see results

Related

how to find classes from dbpedia?

I need a sparql query that given a free text (user input),
it finds me from dbpedia all the classes related to it.
How do it?
Also asked here. Accepted answer said --
When you say classes, are you mean about types? If yes, try something like
SELECT ?uri ?label ?type
WHERE {
?uri rdfs:label ?label .
?uri <http://dbpedia.org/ontology/type> ?type .
FILTER regex(str(?label), "Leipzig") .
}
limit 10
I couldn't let this go...
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX virtdrf: <http://www.openlinksw.com/schemas/virtrdf#>
SELECT ?s1c AS ?c1
COUNT (*) AS ?c2
?c3
WHERE
{
QUAD MAP virtrdf:DefaultQuadMap
{
GRAPH ?g
{
?s1 ?s1textp ?o1 .
?o1 bif:contains '"dbpedia"' .
}
}
?s1 a ?s1c .
OPTIONAL { ?s1c rdfs:label ?c3
FILTER(langMatches(LANG(?c3),"EN"))}
}
GROUP BY ?s1c ?c3
ORDER BY DESC (2) ASC (3)
The earlier answer gets you partial results.

DBPedia Sparql with one request get links for multiple resources

Currently I'm doing for every entity that I have a single request to the sparql endpoint to get all the links for it e.g.
SELECT * WHERE {
{<http://dbpedia.org/resource/San_Francisco> rdf:type ?link}
}
I want to make it more efficient, and I would like to know if there is a way to get the links for multiple entities with one request. I threw something together but this gives me just a big list with all the links.
SELECT * WHERE {
{<http://dbpedia.org/resource/San_Francisco> rdf:type ?link}
UNION
{<http://dbpedia.org/resource/Silicon_Valley> rdf:type ?link}
}
Can I somehow get the links, so I can identify to which entity they belong?
You can be a little more succinct with the SPARQL 1.1 values keyword:
SELECT *
WHERE
{ VALUES ?entity { <http://dbpedia.org/resource/San_Francisco>
<http://dbpedia.org/resource/Silicon_Valley> }
?entity rdf:type ?link
}
Do you want a distinct list? Maybe sort the list and add English-language labels if available?
SELECT DISTINCT ?link ?llab
WHERE
{ VALUES ?entity { <http://dbpedia.org/resource/San_Francisco>
<http://dbpedia.org/resource/Silicon_Valley> }
?entity rdf:type ?link
OPTIONAL
{ ?link rdfs:label ?llab
FILTER ( lang(?llab) = "en" )
}
}
ORDER BY ?link

DBpedia SPARQL filter does not apply to all results

A FILTER NOT EXISTS allows some results through when combined with OPTIONAL triples.
My query:
SELECT DISTINCT * WHERE
{
{
?en rdfs:label "N'Djamena"#en .
BIND("N'Djamena" AS ?name) .
}
UNION {
?en rdfs:label "Port Vila"#en .
BIND("Port Vila" AS ?name) .
}
UNION {
?en rdfs:label "Atafu"#en .
BIND("Atafu" AS ?name) .
}
FILTER NOT EXISTS { ?en rdf:type skos:Concept } .
OPTIONAL { ?en owl:sameAs ?es . FILTER regex(?es, "es.dbpedia") . }
OPTIONAL { ?en owl:sameAs ?pt . FILTER regex(?pt, "pt.dbpedia") . }
}
LIMIT 100
This query gets the three places as expected, but it also pulls back "Category:Atafu", which should be filtered out by virtue of having "rdf:type skos:Concept".
When used without the OPTIONAL lines, I get the three places expected. When used with those clauses non-optionally, I get only two of the countries, because Atafu doesn't have a page in Portuguese.
I can also move the FILTER NOT EXISTS statement into each of the UNION'd country blocks, but that seems to hurt the server's response time.
Why does the FILTER NOT EXISTS clause filter out "Category:N'Djamena" and Category:Port_Vila but not "Category:Atafu" when followed by OPTIONAL?
I really have no idea why your query doesn't work. I'd have to chalk it up to some weird Virtuoso thing. There's definitely something strange going on. For instance, if you remove the bind for the last name, you'll get the resources you're expecting:
SELECT DISTINCT * WHERE
{
{
?en rdfs:label "N'Djamena"#en .
BIND("N'Djamena" AS ?name) .
}
UNION {
?en rdfs:label "Port Vila"#en .
BIND("Port Vila" AS ?name) .
}
UNION {
?en rdfs:label "Atafu"#en .
}
FILTER NOT EXISTS { ?en rdf:type skos:Concept }
OPTIONAL { ?en owl:sameAs ?es . FILTER regex(?es, "es.dbpedia") }
OPTIONAL { ?en owl:sameAs ?pt . FILTER regex(?pt, "pt.dbpedia") . }
}
LIMIT 100
SPARQL results
It's really pretty weird. Here's a modified version of your query that gets the results you're looking for. It uses values instead of union, which makes the query simpler. It should be logically equivalent, though, so I'm not sure why it makes a difference.
select distinct * where {
values ?label { "N'Djamena"#en "Port Vila"#en "Atafu"#en }
?en rdfs:label ?label .
optional { ?en owl:sameAs ?pt . filter regex(?pt, "pt.dbpedia") }
optional { ?en owl:sameAs ?es . filter regex(?es, "es.dbpedia") }
filter not exists { ?en a skos:Concept }
bind(str(?label) as ?name)
}
SPARQL results
I'd actually clean up the string matching though, since regular expressions are probably more power than you need here. You just want to check whether the value starts with a given substring:
select ?en ?label (str(?label) as ?name) ?es ?pt where {
values ?label { "N'Djamena"#en "Port Vila"#en "Atafu"#en }
?en rdfs:label ?label .
optional { ?en owl:sameAs ?pt . filter strstarts(str(?pt), "http://pt.dbpedia") }
optional { ?en owl:sameAs ?es . filter strstarts(str(?es), "http://es.dbpedia") }
filter not exists { ?en a skos:Concept }
}
SPARQL results

Query for resources using their URIs

I have a bunch of resource URIs, and I need the property values related to each of them. For a single resource, say <http://my.url/res#resourceUri>, I can write this query:
PREFIX v: <http://my.url/res#>
SELECT ?name
WHERE {
<http://my.url/res#resourceUri> a v:t;
rdfs:label ?name .
}
For multiple resources, I can use UNION, like this:
PREFIX v: <http://my.url/res#>
SELECT ?name
WHERE {
{ <http://my.url/res#resourceUri> a v:t; rdfs:label ?name } UNION
{ <http://my.url/res#anotherResource> a v:t; rdfs:label ?name }
}
Is there a way to write a shorter, leaner version of this second query?
You can use values for this. Your example would be written as
PREFIX v: <http://my.url/res#>
SELECT ?resource ?name WHERE {
values ?resource { <http://my.url/res#resourceUri>
<http://my.url/res#anotherResource> }
?resource a v:t;
rdfs:label ?name
}
The question is different, but the answer to how to use Union/or in sparql path with arbitrary length? is similar.

Simplify SPARQL query

I’m trying to make a rather complex call to DBPedia using a SPARQL query. I’d like to get some information about a city (district, federal state/»Bundesland«, postal codes, coordinates and geographically related cities).
Try online!
SELECT * WHERE {
#input
?x rdfs:label "Bentzin"#de.
#district
OPTIONAL {
?x dbpedia-owl:district ?district
# ?x dbpprop:landkreis ?district
{ SELECT * WHERE {
?district rdfs:label ?districtName
FILTER(lang(?districtName) = "de")
?district dbpprop:capital ?districtCapital
{ SELECT * WHERE {
?districtCapital rdfs:label ?districtCapitalName
FILTER(lang(?districtCapitalName) = "de")
}}
}}
}
#federal state
OPTIONAL {
# ?x dbpprop:bundesland ?land
?x dbpedia-owl:federalState ?land
{ SELECT * WHERE {
?land rdfs:label ?landName
FILTER(lang(?landName) = "de")
}}
}
#postal codes
?x dbpedia-owl:postalCode ?zip.
#coordinates
?x geo:lat ?lat.
?x geo:long ?long
#cities in the south
OPTIONAL {
?x dbpprop:south ?south
{SELECT * WHERE {
?south rdfs:label ?southName
FILTER(lang(?southName) = "de")
}}
}
#cities in the north
OPTIONAL {
?x dbpprop:north ?north
{ SELECT * WHERE {
?north rdfs:label ?northName
FILTER(lang(?northName) = "de")
}}
}
#cities in the west
...
}
This works in some cases, however, there are a few major problems.
There are several different properties that may contain the value for the federal state or district. Sometimes it’s dbpprop:landkreis (the german word for district, in other cases it’s dbpedia-owl:district. Is it possible to combine those two in cases where only one of them is set?
Further, I’d like to read out the names of the cities in the north, northwest, …. Sometimes, these cities are referenced in dbpprop:north etc. The basic query for each direction is the same:
OPTIONAL {
?x dbpprop:north ?north
{ SELECT * WHERE {
?north rdfs:label ?northName
FILTER(lang(?northName) = "de")
}}
}
I really don’t want to repeat that eight times for every direction, is there any way to simplify this?
Sometimes, there are multiple other cities referenced (example). In those cases, there are multiple datasets returned. Is there any possibility to get a list of the names of those cities in a single dataset instead?
+---+---+---------------------------------------------------------------+
| x | … | southName |
+---+---+---------------------------------------------------------------+
| … | … | "Darmstadt"#de, "Stuttgart"#de, "Karlsruhe"#de, "Mannheim"#de |
+---+---+---------------------------------------------------------------+
Your feedback and your ideas are greatly appreciated!
Till
There are several different properties that may contain the value for the federal state or district. Sometimes it’s dbpprop:landkreis (the
german word for district, in other cases it’s dbpedia-owl:district. Is
it possible to combine those two in cases where only one of them is
set?
SPARQL property paths are great for this. You can just say
?subject dbprop:landkreis|dbpedia-owl:district ?district
If there are more properties, you'll probably prefer a version with values:
values ?districtProperty { dbprop:landkreis dbpedia-owl:district }
?subject ?districtProperty ?district
Further, I’d like to read out the names of the cities in the north,
northwest, …. Sometimes, these cities are referenced in dbpprop:north
etc. The basic query for each direction is the same:
OPTIONAL {
?x dbpprop:north ?north
{ SELECT * WHERE {
?north rdfs:label ?northName
FILTER(lang(?northName) = "de")
}}
}
Again, it's values to the rescue. Also, don't use lang(…) = … to filter languages, use langMatches:
optional {
values ?directionProp { dbpprop:north
#-- ...
dbpprop:south }
?subject ?directionProp ?direction
optional {
?direction rdfs:label ?directionLabel
filter langMatches(lang(?directionLabel),"de")
}
}
Sometimes, there are multiple other cities referenced (example). In
those cases, there are multiple datasets returned. Is there any
possibility to get a list of the names of those cities in a single
dataset instead?
+---+---+---------------------------------------------------------------+
| x | … | southName |
+---+---+---------------------------------------------------------------+
| … | … | "Darmstadt"#de, "Stuttgart"#de, "Karlsruhe"#de, "Mannheim"#de |
+---+---+---------------------------------------------------------------+
That's what group by and group_concat are for. See Aggregating results from SPARQL query. I don't actually see these results in the query you gave though, so I don't have good data to test a result with.
You also seem to be doing a lot of unnecessary subselects. You can just put additional triples in the graph pattern; you don't need a nested query to get additional information.
With those considerations, your query becomes:
select * where {
?x rdfs:label "Bentzin"#de ;
dbpedia-owl:postalCode ?zip ;
geo:lat ?lat ;
geo:long ?long
#-- district
optional {
?x dbpedia-owl:district|dbpprop:landkreis ?district .
?district rdfs:label ?districtName
filter langMatches(lang(?districtName),"de")
optional {
?district dbpprop:capital ?districtCapital .
?districtCapital rdfs:label ?districtCapitalName
filter langMatches(lang(?districtCapitalName),"de")
}
}
#federal state
optional {
?x dbpprop:bundesland|dbpedia-owl:federalState ?land .
?land rdfs:label ?landName
filter langMatches(lang(?landName),"de")
}
values ?directionProp { dbpprop:south dbpprop:north }
optional {
?x ?directionProp ?directionPlace .
?directionPlace rdfs:label ?directionName
filter langMatches(lang(?directionName),"de")
}
}
SPARQL results
Now, if you're just looking for the names of these things, without the associated URIs, you can actually use property paths to shorten a lot of the results that retrieve labels. E.g.:
select * where {
?x rdfs:label "Bentzin"#de ;
dbpedia-owl:postalCode ?zip ;
geo:lat ?lat ;
geo:long ?long
#-- district
optional {
?x (dbpedia-owl:district|dbpprop:landkreis)/rdfs:label ?districtName
filter langMatches(lang(?districtName),"de")
optional {
?district dbpprop:capital/rdfs:label ?districtCapitalName
filter langMatches(lang(?districtCapitalName),"de")
}
}
#-- federal state
optional {
?x (dbpprop:bundesland|dbpedia-owl:federalState)/rdfs:label ?landName
filter langMatches(lang(?landName),"de")
}
optional {
values ?directionProp { dbpprop:south dbpprop:north }
?x ?directionProp ?directionPlace .
?directionPlace rdfs:label ?directionName
filter langMatches(lang(?directionName),"de")
}
}
SPARQL results