Understanding CONSTRUCT templates - sparql

I'm learning SPARQL right now, and I'm having trouble understanding the limits of CONSTRUCT templates. Normally everything works fine, just about the way I'd expect it to. However, my understanding breaks down when I start to make templates that don't semantically make sense. Here's an example:
I have the following data stored:
me: a foaf:Person .
foaf:mbox rdfs:label "Email" .
With a default template of ?s ?p ?o, I obviously get that exact data back. If I go for something a bit nonsenical, like this:
CONSTRUCT {
?type ?labeled ?label
}
WHERE {
me: a ?type .
?labeled rdfs:label ?label .
}
I get back this triple:
foaf:Person foaf:mbox "Email" .
This kinda makes sense to me, because there's three variables, and each has only one value it can bind to in the dataset. However, as soon as I switch the order of the variables in the template to be like this: ?type ?label ?labeled, I get literally nothing back. Why is that? The template ?type ?labeled ?label already breaks the original structure of the data and I still get something back, so why would ?type ?label ?labeled be any different?

As noted by #AKSW, literals can't be predicates. "Email" is a literal, and thus it couldn't be CONSTRUCTed into a predicate position.

Related

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.)

Retrieving the wider dbpedia vocabulary for tagging pictures

I'm trying to develop a tool in JS for tagging pictures, so I need a set of possible "things" from dbpedia. I already tryed to retrieve this way:
select ?s ?l {
?s a owl:Class .
?s rdf:type ?l
FILTER regex(str(?s), "House", "i").
}
http://dbpedia.org/snorql/?query=select+%3Fs+%3Fl+%7B%0D%0A+++%3Fs+a+owl%3AClass+.%0D%0A+++%3Fs+rdf%3Atype+%3Fl%0D%0A+++FILTER+regex%28str%28%3Fs%29%2C+%22House%22%2C+%22i%22%29.%0D%0A%7D
And also this way:
select ?label
WHERE {
?concept a skos:Concept.
?concept skos:prefLabel ?label.
FILTER regex(str(?label), "^House", "i").
}
http://dbpedia.org/snorql/?query=select+%3Flabel+%0D%0AWHERE+%7B%0D%0A++%3Fconcept+a+skos%3AConcept.%0D%0A++%3Fconcept+skos%3AprefLabel+%3Flabel.%0D%0A++FILTER+regex%28str%28%3Flabel%29%2C+%22%5EHouse%22%2C+%22i%22%29.%0D%0A%7D
In the first case, I just have "instances" of the house "thing", but not the "House" class itself. In the second one, I never retrieve the "house" and the similar thing is "houses". Any alternative for retrieving a better vocabulary based in dbpedia dataset?
If you don't bother to restrict yourself to owl:Thing or to skos:Concept, you can just get things that have a label that contains "house". Rather than using regex, I chose to use contains and lcase, since a string containment could be less expensive than invoking a full regular expression processor.
select ?thing ?label where {
?thing rdfs:label ?label .
filter contains(lcase(?label), "house")
}
SPARQL results (limited to 200)

DBpedia Sparql by page template

I am trying to run a query on dbpedia using SPARQL syntax, to look for all pages of a certain template. Doesn't seem to be work, I am looking for all pages with dbpprop:wikiPageUsesTemplate. Does anyone know how to correct this to properly look for templates?
SELECT ?name ?member_Of ?country ?lat ?lng ?link
WHERE {
?x dbpprop:wikiPageUsesTemplate "dbpedia:Template:Infobox_settlement" .
?x a <http://dbpedia.org/ontology/Settlement> .
?x foaf:name ?name .
?x dbpedia-owl:isPartOf ?member_Of.
?x dbpedia-owl:country ?country.
?x geo:lat ?lat .
?x geo:long ?lng .
?x foaf:isPrimaryTopicOf ?link .
}
LIMIT 2500 OFFSET 0
I've also attempted to run it just by the dbprop to no avail.
SELECT * WHERE { ?page dbpprop:wikiPageUsesTemplate <http://dbpedia.org/resource/Template:Infobox_settlement> . ?page dbpedia:name ?name .}
If anyone is trying to do a similar thing, it is also possible via the wiki api, where you can pagananate over all results. http://en.wikipedia.org/w/api.php?action=query&list=embeddedin&eititle=Template:Infobox_settlement
There are at least two problems: (i) you need to use IRIs in places, and not strings; and (ii) you need to use properties that DBpedia uses.
Use IRIs
In
?x a <http://dbpedia.org/ontology/Settlement> .
and
?x foaf:isPrimaryTopicOf ?link .
you've demonstrated that you know that URIs need to be written in full with < and >, or abbreviated with a prefix. However,
?x dbpprop:wikiPageUsesTemplate "dbpedia:Template:Infobox_settlement" .
certainly isn't going to work. It's legal SPARQL, because a string can be the object of a triple, but you almost certainly want an IRI.
Use DBpedia's vocabulary
A query with dbpprop:wikiPageUsesTemplate like this returns no results:
select distinct ?template where {
[] dbpprop:wikiPageUsesTemplate ?template
}
SPARQL results
That's easy enough to check, and quickly confirms that there's no data that can possibly match your query. Where did you find this property? Have you seen it used somewhere? I'm not confident that you can query DBpedia based on infobox templates. DBpedia is not the same as Wikipedia, and even if the Wikipedia API supports it, it doesn't mean that DBpedia has a counterpart. There is a note on DBpedia Data Set Properties that says:
http://xx.dbpedia.org/property/wikiPageUsesTemplate (will be changed to http://dbpedia.org/ontology/wikiPageUsesTemplate)
but that latter property doesn't seem to be in use on the endpoints either. See my answer to Syntax for Sparql query for pages with specific infobox for more details.

How to retrieve abstract for a DBpedia resource?

I need to find all DBpedia categories and articles that their abstract include a specific word.
I know how to write a SPARQL query that queries the label like the following:
SELECT ?uri ?txt WHERE {
?uri rdfs:label ?txt .
?txt bif:contains "Machine" .
}
but I have not figured out yet how to search the abstract.
I've tried with the following but it seems not to be correct.
SELECT ?uri ?txt WHERE {
?uri owl:abstract ?txt .
?txt bif:contains "Machine" .
}
How can I retrieve the abstract in order to query its text?
Since you already know how to search a string for text content, this question is really about how to get the abstract. If you retrieve any DBpedia resource in a web browser, e.g., http://dbpedia.org/resource/Mount_Monadnock (which will redirect to http://dbpedia.org/page/Mount_Monadnock), you can see the triples of which it's a subject or predicate. In this case, you'll see that the property is dbpedia-owl:abstract. Thus you can do things like
select * where {
?s dbpedia-owl:abstract ?abstract .
?abstract bif:contains "Monadnock" .
filter langMatches(lang(?abstract),"en")
}
limit 10
SPARQL results
Instead of visiting the page for the resource, which not endpoints will support, you could have simply retrieved all the triples for the subject, and looked at which ones relate it to its abstract. Since you know the abstract is a literal, you could even restrict it to triples where the object is a literal, and perhaps with a language that you want. E.g.,
select ?p ?o where {
dbpedia:Mount_Monadnock ?p ?o .
filter ( isLiteral(?o) && langMatches(lang(?o),'en') )
}
SPARQL results
This also clearly shows that the property you want is http://dbpedia.org/ontology/abstract. When you have a live query interface that you can use to pull down arbitrary data, it's very easy to find out what parts of the data you want. Just pull down more than you want at first, and then refine to get just what you want.

Sparql to recover the Type of a DBpedia resource

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