SPARQL: How to combine two subjects to use in CONSTRUCT? - sparql

I am writing an SPARQL query where I am creating an RDF graph. I am using SPARQL CONSTRUCT. As a requirement of my work, I have to concatenate two subject values and used it with CONSTRUCT statement. I have tried to do following (my RDF graph is in Virtuoso):
prefix map: <#>
prefix db: <>
prefix vocab: <vocab/>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
prefix d2rq: <http://www.wiwiss.fu-berlin.de/suhl/bizer/D2RQ/0.1#>
prefix jdbc: <http://d2rq.org/terms/jdbc/>
prefix fn: <http://www.w3.org/2005/xpath-functions#>
CONSTRUCT {
?p1 a d2rq:ClassMap
}
FROM <http://www.ndssl.bi.vt.edu/fuse>
WHERE
{
<http://www.ndssl.bi.vt.edu/fuse#DataSource> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#Class>.
<http://www.ndssl.bi.vt.edu/fuse#OracleDataSource> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://www.ndssl.bi.vt.edu/fuse#DataSource>.
?DB <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.ndssl.bi.vt.edu/fuse#OracleDataSource>.
<http://www.ndssl.bi.vt.edu/fuse#HouseholdsWithinAdminRegion> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#Class>.
?Table <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.ndssl.bi.vt.edu/fuse#HouseholdsWithinAdminRegion>.
BIND(CONCAT(?DB, ?Table) AS ?p1)
}
However, I am getting following Error:
Virtuoso RDF01 Error Bad variable value in CONSTRUCT: "http://www.ndssl.bi.vt.edu/fuse#PROTOPOPhttp://www.ndssl.bi.vt.edu/fuse#MIAMI_HOUSEHOLD_2009_1" (tag 246 box flags 0) is not a valid subject, only object of a triple can be a literal
Please let me know how to solve it.

The error is basically saying that you are concatenating two URIs:
http://www.ndssl.bi.vt.edu/fuse#PROTOPOP
http://www.ndssl.bi.vt.edu/fuse#MIAMI_HOUSEHOLD_2009_1
into a literal. I don't know what you are exactly trying to do, but do you really want to concat the WHOLE URI or only the last part after the #? If you want to concat after the # you need to omit the namespace.
bind (concat(strafter(str(?s),str(fuse:)), strafter(str(?o),str(fuse:))) as ?p)
Even at this stage the result of the bind is a literal that you need to convert into a URI.
bind (uri(concat(strafter(str(?s),str(fuse:)), strafter(str(?o),str(fuse:)))) as ?p)
Generally I would simplify your query massively:
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix fuse: <http://www.ndssl.bi.vt.edu/fuse#>
prefix owl:<http://www.w3.org/2002/07/owl#>
CONSTRUCT {
?p1 a d2rq:ClassMap
}
FROM <http://www.ndssl.bi.vt.edu/fuse>
WHERE
{
fuse:DataSource a owl:Class.
fuse:OracleDataSource rdfs:subClassOf fuse:DataSource.
?DB a fuse:DataSource.
fuse:HouseholdsWithinAdminRegion a owl:Class.
?Table a fuse:HouseholdsWithinAdminRegion.
bind (uri(concat(strafter(str(?DB),str(fuse:)),
strafter(str(?Table),str(fuse:)))) as ?p)
}

Related

Apply literal type to object in INSERT query

In a certain knowledge graph there is a large number of individuals that need
to be assigned a literal token of the type xsd:token. It is not practical to
do so manually, therefore I am trying with an INSERT instruction. However, I
can't find a way to assign the desired literal type in that kind of query.
Consider in first place this basic example knowledge graph:
#prefix : <http://my.example.web/> .
#prefix foaf: <http://xmlns.com/foaf/0.1/> .
:1 a foaf:Person ;
foaf:name "Jane Doe" .
:2 a foaf:Person ;
foaf:name "John Smith" .
The exercise would be to add a token created by removing the blank spaces from
the foaf:name literal. For the :1 this would translate into the addition of the triple:
:1 dcterms:identifier "JaneDoe"^^xsd:token .
With a SELECT query I can archive it the following
way:
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT STRDT(?token, xsd:token)
WHERE {
GRAPH <http://my.example.web/> {
?s foaf:name ?name .
BIND(REPLACE(STR(?name)," ","") AS ?token) .
}
}
Which produces the result:
LONG VARCHAR
_______________________________________________________________________________
JaneDoe
JohnSmith
2 Rows. -- 54 msec.
Now using the same formulation, but with an INSERT query:
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX dcterms: <http://purl.org/dc/terms/>
INSERT
{
GRAPH <http://my.example.web/> {
?s dcterms:identifier STRDT(?token, xsd:token) .
}
}
WHERE {
GRAPH <http://my.example.web/> {
?s foaf:name ?name .
BIND(REPLACE(STR(?name)," ","") AS ?token) .
}
}
An error is the result:
*** Error 37000: [Virtuoso Driver][Virtuoso Server]SQ074: Line 17 (line 17 of "(console)"): SP030: SPARQL compiler, line 9: syntax error at 'STRDT' before '('
In essence I need a way to apply the STRDT function to the
object of a triple inside the INSERT clause. Or any other alternative mechanism allowing to set a literal type in this kind of query.
Both your queries are invalid:
SELECT STRDT(?token, xsd:token)
According to the SelectClause production, an expression must be followed by AS to give it a variable binding. In essence, you have to use the same syntax you would have used after BIND (you also need parentheses around it). As for why Virtuoso accepts this, well Virtuoso does not strictly follow all of SPARQL ‒ it also allows , between the variables in SELECT, has the DEFINE clause, and allows undeclared prefixes if they are recognized by the store.
This is valid:
SELECT (STRDT(?token, xsd:token) AS ?tokenTyped)
or modify the BIND:
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?token
WHERE {
GRAPH <http://my.example.web/> {
?s foaf:name ?name .
BIND(STRDT(REPLACE(STR(?name)," ",""), xsd:token) AS ?token) .
}
}
This seems the cleanest to me.
Likewise, for the second query, you cannot have an expression as an object of a triple (or any position for that matter), see the Object production. Using a variable is the best the syntax allows you to do (while it would certainly be nice to be able to use expressions as you wanted):
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX dcterms: <http://purl.org/dc/terms/>
INSERT
{
GRAPH <http://my.example.web/> {
?s dcterms:identifier ?token .
}
}
WHERE {
GRAPH <http://my.example.web/> {
?s foaf:name ?name .
BIND(STRDT(REPLACE(STR(?name)," ",""), xsd:token) AS ?token) .
}
}
I have tested it and it should work on OpenLink Virtuoso version 07.20.3231. If you have issues with this, perhaps the Virtuoso instance needs to be updated, or refer to GitHub.

SPARQL Query returns empty result set

I am querying marine data via SPARQL. I developed a SPARQL console with CodeMirror, RDFLib and SPARQLWrapper in order to display a number of predefined queries and results in my website. In the console, the query:
prefix geo: <https://www.w3.org/2003/01/geo/wgs84_pos#>
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix ssn: <http://www.w3.org/ns/ssn/>
prefix xml: <http://www.w3.org/XML/1998/namespace>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
prefix argo: <http://www.argodatamgt.org/argo-ontology#>
prefix foaf: <http://xmlns.com/foaf/0.1/>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix sosa: <http://www.w3.org/ns/sosa/>
prefix nerc: <http://vocab.nerc.ac.uk/collection/>
prefix dct: <http://purl.org/dc/terms/>
prefix prov: <https://www.w3.org/TR/prov-o/>
# stations/date of each cycle
SELECT distinct ?wmo ?lat ?lon ?date where{
?float argo:cycle ?cycle;
argo:wmoCode ?wmo.
?cycle geo:latitude ?lat;
geo:longitude ?lon;
argo:startDate ?date.
}
returns nothing. I cross-checked it by using https://www.orpha.net/sparql , a query editor, and the result was the same - empty result set.
However, when I try the exact same query in the research infrastructure's SPARQL Endpoint https://www.ifremer.fr/co/argo-linked-data/html/Argo-HTML-SPARQL/ , it works flawlessly.
I have tried very generic queries like:
SELECT DISTINCT * WHERE {
?s ?p ?o
}
LIMIT 10
or
select distinct ?p ?label
where {
?s ?p ?o .
OPTIONAL { ?p rdfs:label ?label }
}
and they return non-empty results both in my console and in the generic SPARQL editor I mentioned before.
Performing a CURL request, modifying the template query by the first mentioned "stations/date of each cycle" one I am able to get the data:
curl -X POST "https://sparql.ifremer.fr/argo/query" --data-urlencode "query=select ?s ?o ?p where{?s ?o ?p.} limit 10"
This makes me think that an outdated Virtuoso server on their side might be the culprit, however, I am very new in SPARQL and Semantics to tell and I would appreciate any clue.
As OP said in comment --
I found the culprit and it was an error from my side. I am using SPARQLWrapper and somewhere in my code I had a fixed SPARQL endpoint from another research infrastructure, I totally missed that.

freetext search in dbpedia

I want to use freetext search against the dbpedia and I'm trying the query I found on the W3C website: https://www.w3.org/2009/Talks/0615-qbe/
If I try the query WITHOUT the bif: prefix by commenting it out I get the error shown below the query:
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX type: <http://dbpedia.org/class/yago/>
PREFIX prop: <http://dbpedia.org/property/>
# PREFIX bif: <http://www.openlinksw.com/schemas/bif#>
SELECT ?lbl ?est
WHERE {
?country rdfs:label ?lbl .
FILTER(bif:contains(?lbl, "Republic")) .
?country a type:Country108544813 ;
prop:establishedDate ?est .
FILTER(?est < "1920-01-01"^^xsd:date) .
}
Error: Line 9, Parse error: namespace mapping for "bif" not defined
when expanding QName "bif:contains".
[condition type: sparql-lexer-error-namespace-mapping-not-defined]
well: that makes sense, you do need to define your namespace. So let me do the same query again using the bif: prefix that I found on the Virtuoso website (and various other places)
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX type: <http://dbpedia.org/class/yago/>
PREFIX prop: <http://dbpedia.org/property/>
PREFIX bif: <http://www.openlinksw.com/schemas/bif#>
SELECT ?lbl ?est
WHERE {
?country rdfs:label ?lbl .
FILTER(bif:contains(?lbl, "Republic")) .
?country a type:Country108544813 ;
prop:establishedDate ?est .
FILTER(?est < "1920-01-01"^^xsd:date) .
}
Now I get a different error: it seems that the bif: namespace is a protected name by Virtuoso
So it seems I cannot live with bif: or without :bif. Has anyone seen this error before? Thanks.
Btw: I really don't care that much about bif: What I really want is to do freetext queries against dbpedia. So any alternative is welcome. YES: there are earlier questions on SO about this but note that each of those answers contain bif: as well.
Added later: so just to be sure I changed bif: into bof: and now I get a new error that shows that contains no longer is a valid operator. See below. So anyway: I guess the only thing I care about from here on is: how do you do freetext queries against dbpedia :-)
bif: is a Virtuoso built-in, for "built-in function".
You're going through some sort of SPARQL pre-parser, not directly against the SPARQL endpoint, so you do need to define the prefix in your query. Most such pre-parsers will do the right thing if you just --
PREFIX bif: <bif:>
Alternatively, you can change your query from using the bif:contains function --
FILTER(bif:contains(?lbl, "Republic"))
-- to use SPARQL regex --
FILTER regex(?lbl, "Republic")

Running sparql query for getting float values

Hi Below is my sparql query which I am executing on https://dbpedia.org/sparql. However I am getting an error "Invalid floating point value converting 'United States:'" because of the presence of some characters values in grossincome and If I change my query to str(?grossincome) as ?grossincome1) then it executes correctly. My question is how can I convert all currencies on same scale to avoid this error?
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX dcterms: <http://purl.org/dc/terms/>
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX dbp: <http://dbpedia.org/property/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
select distinct (str(?resource) as ?movietitle) (xsd:float(?budget) as ?budget1) (xsd:float(?grossincome) as ?grossincome1) (str(?Country) as ?country1) ?ReleaseDate where {
?movie foaf:name ?resource.
?movie dbo:budget ?budget.
?movie dbp:gross ?grossincome.
?movie dbp:country ?Country.
?movie dbo:releaseDate ?ReleaseDate.
FILTER (lang(?resource) = 'en').
}
The data in DBpedia is not perfect as you already recognized it's quite heterogeneous for the untyped property dbp:gross. Among others, it contains values like BDT 2.52 crores, $34,994,648 USD, AU$178,000, 6892098.0, so it is almost impossible to handle different currencies via a SPARQL query such that it returns the values in the same currency.
I mean, you would have to know all different currencies and formats that occur and then handle each separately. But that's more the task of application logic and not the query itself.
Alternatively, you could try to use the data property http://dbpedia.org/ontology/gross instead, which is supposed to relate to values in $. At least that's what its label "gross ($)" states.

Sparql result not containing specified property included in results

I have this query
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX dbpedia: <http://dbpedia.org/>
PREFIX dbpedia_property: <http://dbpedia.org/property/>
PREFIX dbpedia_ontology: <http://dbpedia.org/ontology/>
PREFIX yago: <http://dbpedia.org/class/yago/>
PREFIX schema: <http://schema.org/>
SELECT * WHERE
{
{
SELECT ?school
WHERE
{
?school rdf:type yago:EducationalInstitution108276342 .
FILTER ( contains(str(?school), "Australia") )
}
ORDER BY ?school
}
}
Don't mind the extra brackets as this is part of a larger query.
What I want to know is why thi http://dbpedia.org/page/Academic_structure_of_the_Australian_National_University is included in the results since I specify rdf:type yago:EducationalInstitution108276342. This property is not included in the resource page. I'm using this endpoint: http://dbpedia.org/sparql
Looks like a bug in the Pubby Web interface or in the query that is used to get the data that will be shown.
The query
SELECT * WHERE{
<http://dbpedia.org/resource/Academic_Structure_of_the_Australian_National_University> ?p ?o
}
returns the necessary rdf:type statement.
The other strange thing is that even a SPARQL DESCRIBE query does not return the rdd:type triples:
DESCRIBE <http://dbpedia.org/resource/Academic_Structure_of_the_Australian_National_University>
Although DESCIBE is not really defined in the specs, a user would expect those triples for sure. And maybe this kind of query is used to retrieve the data for the Web pages of resources.