Sparql to recover the Type of a DBpedia resource - sparql

I need a Sparql query to recover the Type of a specific DBpedia resource. Eg.:
pt.DBpedia resource: http://pt.dbpedia.org/resource/Argentina
Expected type: Country (as can be seen at http://pt.dbpedia.org/page/Argentina)
Using pt.DBpedia Sparql Virtuoso Interface (http://pt.dbpedia.org/sparql) I have the query below:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?l ?t where {
?l rdfs:label "Argentina"#pt .
?l rdf:type ?t .
}
But it is not recovering anything, just print the variable names. The virtuoso answer.
Actually I do not need to recover the label (?l) too.
Anyone can fix it, or help me to define the correct query?

http in graph name
I'm not sure how you generated your query string, but when I copy and paste your query into the endpoint and run it, I get results, and the resulting URL looks like:
http://pt.dbpedia.org/sparql?default-graph-uri=http%3A%2F%2Fpt.dbpedia.org&sho...
However, the link in your question is:
http://pt.dbpedia.org/sparql?default-graph-uri=pt.dbpedia.org%2F&should-sponge...
If you look carefully, you'll see that the default-graph-uri parameters are different:
yours: pt.dbpedia.org%2F
mine: http%3A%2F%2Fpt.dbpedia.org
I'm not sure how you got a URL like the one you did, but it's not right; the default-graph-uri needs to be http://pt.dbpedia.org, not pt.dbpedia.org/.
The query is fine
When I run the query you've provided at the endpoint you've linked to, I get the results that I'd expect. It's worth noting that the label here is the literal "Argentina"#pt, and that what you've called ?l is the individual, not the label. The individual ?l has the label "Argentina"#pt.
We can simplify your query a bit, using ?i instead of ?l (to suggest individual):
select ?i ?type where {
?i rdfs:label "Argentina"#pt ;
a ?type .
}
When I run this at the Portuguese endpoint, I get these results:
If you don't want the individual in the results, you don't have to select it:
select ?type where {
?i rdfs:label "Argentina"#pt ;
a ?type .
}
or even:
select ?type where {
[ rdfs:label "Argentina"#pt ; a ?type ]
}
If you know the identifier of the resource, and don't need to retrieve it by using its label, you can even just do:
select ?type where {
dbpedia-pt:Argentina a ?type
}
type
==========================================
http://www.w3.org/2002/07/owl#Thing
http://www.opengis.net/gml/_Feature
http://dbpedia.org/ontology/Place
http://dbpedia.org/ontology/PopulatedPlace
http://dbpedia.org/ontology/Country
http://schema.org/Place
http://schema.org/Country

Related

How to query for publication date of books using SPARQL in DBPEDIA

I am trying to retrieve the publication date and the no.of pages for books in DBpedia. I tried the following query and it gives empty results. I see that these are properties under book(http://mappings.dbpedia.org/server/ontology/classes/Book) but could not retrieve it.
I would like to know if there is an error in the code or if dbpedia does not store these dates related to books.
SELECT ?book ?genre ?date ?numberOfPages
WHERE {
?book rdf:type dbpedia-owl:Book .
?book dbp:genre ?genre .
?book dbp:firstPublicationDate ?date .
OPTIONAL {?book dbp:numberOfPages ?numberOfPages .}
}
The dbp:firstPublicationDate does not work for two reasons:
First, as pointed in the first answer, you used the wrong prefix.
But even if you correct it, you'll see that you would still have no results. Then the best thing to do is to test with the minimum number of patters, in you case you should as for books with first publication date, two triple pattern only. If you still don't get results, you should test how <http://dbpedia.org/ontology/firstPublicationDate> is actually used with a query like this:
SELECT ?class (COUNT (DISTINCT ?s) AS ?instances)
WHERE {
?s <http://dbpedia.org/ontology/firstPublicationDate> ?date ;
a ?class
}
GROUP BY ?class
ORDER BY DESC(?instances)
LIMIT 1000
Mapping based properties are using the namespace http://dbpedia.org/ontology/, thus, the prefix must be dbo instead of dbp, which stands for http://dbpedia.org/property/.
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX dbp: <http://dbpedia.org/property/>
SELECT ?book ?genre ?date ?numberOfPages
WHERE {
?book a dbo:Book ;
dbp:genre ?genre ;
dbo:firstPublicationDate ?date .
OPTIONAL {?book dbp:numberOfPages ?numberOfPages .}
}
Some additional comments:
put the prefixes to the SPARQL query such that others here can run it without any exceptions (also in the future) - the current SPARQL query uses dbpedia-owl but this one is not pre-defined on the official DBpedia anymore - it's called dbo instead
which brings me to the second point -> if you're using a public SPARQL endpoint, show its URL
you can start debugging your own SPARQL query by simply starting with only parts of it and adding more triple patterns then, e.g. in your case you could check if there is any triple with the property with
PREFIX dbp: <http://dbpedia.org/property/>
SELECT * WHERE {?book dbp:firstPublicationDate ?date } LIMIT 10
Update
As Ivo Velitchkov noticed in his answer below, the property dbo:firstPublicationDate is only used for mangas, etc., i.e. written work that was published periodically. Thus, the result will be empty.

Multiple SELECT query for getting all children of a given root

I want to define the root categories corresponding to interests of users. Then I need to return all other potential interests under given root directory.
I tried the following query, but it looks like it enters into a loop (the query is executing internally).
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.myweb.com/myontology.owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?user ?othercat
WHERE
{
?othercat rdfs:subClassOf ?root .
{
SELECT ?user ?retailcat ?root
WHERE {
?user rdf:type owl:User .
?user owl:hasUserProfile ?userprofile .
?userprofile rdf:type owl:UserProfile .
?userprofile owl:interestedIn ?retailcat .
?entity rdf:type ?type .
?type rdfs:subClassOf* ?retailcat .
?retailcat rdfs:subClassOf ?root .
}
}
}
Indeed when I execute the sub-query, it works fine, but it returns current interests of a user, without providing the information of other child-concepts of the same root.
How to solve this issue?
I tried the following query, but it looks like it enters into a loop (the query is executing internally).
There shouldn't be a way for a SPARQL query to enter into a loop. Subqueries are executed first, and then the enclosing query is executed. There's no way to re-execute the inner part or anything like that. (Of course, a query could be expensive and take a long time, but that's not a loop, and is still bounded, in principle.)
As an aside, using owl: as prefix for something other than the standard OWL namespace is somewhat confusing, and likely to mislead other developers when they see your query. There's nothing incorrect about it per se, but you might want to consider using a different prefix for your namespace.
You do have one part of your query that could make things rather expensive. You have the pattern
?entity rdf:type ?type .
?type rdfs:subClassOf* ?retailcat .
where ?entity isn't connected to anything else, and isn't used anywhere else. That means that you'll have a subquery solution for every possible value of ?entity, and that just means you're multiplying the number of results by the number of possible values of ?entity.
If I understand your query, you're trying to go from a user's categories of interest, up the category tree to some root concepts and then find other categories under that root. You don't actually need a subquery for that; you can do it with a non-nested query:
select ?user ?othercat {
?user rdf:type owl:User .
?user owl:hasUserProfile ?userprofile .
?userprofile rdf:type owl:UserProfile .
?userprofile owl:interestedIn ?retailcat .
?retailcat rdfs:subClassOf ?root .
?othercat rdfs:subClassOf ?root .
}
That will find values of ?othercat that are siblings of ?retailcat, along with ?retailcat itself. If you want to avoid ?retailcat, you can add
filter(?othercat != ?retailcat)
but that shouldn't really impact performance much; that's just one result to filter out.
The only other factor that you might want to consider is that you're not really finding a "root" of the category tree with rdfs:subClassOf; you're just going up one level. E.g., if your category tree looks like
Automobile
SUV
SportsCar
Corvette
Mustang
and a user is interested in Mustang, then you'll go up to SportsCar and find Corvette, but you won't be going any farther up the tree. (If you have inference available, you may actually go farther up the tree, but I'm assuming for the moment that you don't.) To follow the subclass links up the tree, you can add * to the path to follow the chain:
?retailcat rdfs:subClassOf* ?root .
?othercat rdfs:subClassOf ?root .
Then you'd get all the classes in the tree (except the very top level one, Automobile).

using bind concat in construct query

I have the following query
CONSTRUCT{
?entity a something;
a label ?label .
}
WHERE
{
?entity a something;
a label ?label .
BIND(CONCAT(STR( ?label ), " | SOME ADDITIONAL TEXT I WOULD LIKE TO APPEND MANUALLY") ) AS ?label ) .
}
I simply want to concatenate some text with ?label, however when running the query I get the following error:
BIND clause alias '?label' was previously used
I only want to return a single instance of ?label hence, I defined it in the construct clause.
The error message seems to be accurate, but is only the first of many you will get with this query. The usual request to take a look at some SPARQL learning resources to at least understand the basics of triple-based graph pattern matching, along with, a couple of hints one what to look for. CONSTRUCT isn't a bad place to start, and the following should almost do what I think you intend:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
CONSTRUCT{
?entity rdfs:label ?label .
}
WHERE
{
?entity a ex:something ;
rdfs:label ?oldlabel .
BIND(CONCAT(STR( ?oldlabel ), " | SOME ADDITIONAL TEXT I WOULD LIKE TO APPEND MANUALLY") ) AS ?label ) .
}
There's quite a few things different about that query, so take a look to see if it accurately does what you want. One hint is the syntactic difference between using '.' and ';' to separate the triple patterns. Another is that each clause defines either a URL, using a qname in the example, or a variable, prefixed by a '?'. Neither 'label' or 'something' are valid.
I say "almost" because CONSTRUCT only returns a set of triples. To modify the labels, which I think is the intent, you need to use SPARQL Update, i.e.:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ex: <http://example.org/example#>
DELETE {
?entity rdfs:label ?oldlabel .
}
INSERT{
?entity rdfs:label ?label .
}
WHERE
{
?entity a ex:something .
?entity rdfs:label ?oldlabel .
BIND(CONCAT(STR( ?oldlabel ), " | SOME ADDITIONAL TEXT I WOULD LIKE TO APPEND MANUALLY") AS ?label ) .
}
Note how the triple pattern finds matches for ?oldlabel and deletes them, inserting the newly bound ?label instead. This query assumes a default graph is defined that holds both the original data and the target for updates. If not then the graph needs to be specified using WITH or GRAPH. (Also included another hint on the syntactic difference between using '.' and ';' to separate triple patterns.)

SPARQL : how to get values for a particular resource?

I am trying this query:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?label
WHERE
{
?AGE rdfs:label ?label.
}
I need all the values of AGE from my model but instead this query is giving me other resources values which have the same property label .
For example I have connected the resource gender to have a property rdfs:label. So in my result I get both age values and gender values.
Can anybody tell me where am I wrong ?
It seems you may be assigning some semantics to the variable '?AGE'. SPARQL is a graph pattern matching language and anything with a '?' as the first character is a variable - or better yet, an unknown in the graph pattern match. I.e., the following is an equivalent query to yours:
SPARQL ?label
WHERE
{ ?s rdfs:label ?label .
}
This will find all triples that have a rdfs:label property and select the value of ?label.
If you have a specific resource you want to query, then specify that resource in the subject, for example:
PREFIX ex: <http://example.org/ex>
SPARQL ?label
WHERE
{ ex:AGE rdfs:label ?label .
}
So understanding the difference between an unknown (denoted by '?' (or '$')) and a known (a qname or a full URI) is important to understand how SPARQL performs graph pattern matching.
Lots of SPARQL learning material on the Web, so a suggestion is to look into some of these to learn some basics.

full text search in jena sparql?

I am new to sparql and I am trying to search a word in one of the property . The simple queries works fine but I don't know how to perform full text search . I saw this example on jena website :
PREFIX text: <http://jena.apache.org/text#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?s
{ ?s text:query (rdfs:label 'word' 10) ;
rdfs:label ?label
}
my model contains property named SUB: and I want to write a query for that . I don't understand what is text and query in text:query means in the above example . Pardon me if this question doesn't meet the requirements of SO.
Link to website:http://jena.apache.org/documentation/query/text-query.html
You may not need a full text index:
SELECT ?s
{ ?s your:property ?o .
FILTER regex(str(?o), "word", "i")
}
but if you do text:query is a "property function" -- it trigger accessing the Apache Lucene index and causing ?s to be bound to each of the answers from a match of 'word' (to a limit of 10) over the rdfs:label properties if you have correctly configured and loaded the data and index.