Constructing a sparql query using rdf4j - sparql

I'm trying to construct a SPARQL query using the rdf4j documentation: https://rdf4j.org/documentation/tutorials/sparqlbuilder/
I am a newbie to java (and stackoverflow, apologies if this is poorly written), but I think I have included the right beginning steps. I have instantiated a select query, a prefix and a variable in the following way:
SelectQuery draftQuery = Queries.SELECT();
Prefix default = SparqlBuilder.prefix("dc", Rdf.iri("url"));
Variable draftCount = SparqlBuilder.var("draftCount");
url has been substituted with the right prefix
The query I am trying to write is: SELECT ?x WHERE { :team_1 :draftCount ?x}, but ?x has no rdf:type and is simply a value that is attached to :draftCount. I have no idea how to write it as a SPARQL query within java, because from what I understand within the docs, the example included where the product is a book, the product has rdf:type "book". I don't want to query multiple variables (e.g. :team_1 ?x ?y) because there are other triples attached to the team and I want to query them separately. I want to have another SPARQL query later that is similar but is SELECT ?x WHERE { :team_1 :completedCount ?x},
How can I write this query? This is what I have so far:
draftQuery.prefix(default).select(draftCount)

You made a good start, but you are mixing up variables and IRIs: :team_1 and :draftCount are IRIs in your query, not variables. Only ?x is a variable. Since you are using the default namespace for your IRs, just create a Prefix object for the default namespace, like so:
Prefix defaultNs = SparqlBuilder.prefix(Rdf.iri("http://example.org/"));
and then you can use that to create Iri objects for use in the query, like so:
Iri team1 = defaultNs.iri("team_1");
To add a relation other than rdf:type using the SparqlBuilder, use the .has method.
Putting it all together, to produce this SPARQL query string:
PREFIX: <http://example.org/>
SELECT ?x WHERE { :team_1 :draftCount ?x}
You do this:
Prefix defaultNs = SparqlBuilder.prefix(Rdf.iri("http://example.org/"));
Iri team_1 = defaultNs.iri("team_1"), draftCount = defaultNs.iri("draftCount");
Variable x = SparqlBuilder.var("x");
SelectQuery query = Queries.SELECT()
.prefix(defaultNs)
.select(x)
.where(team_1.has(draftCount, x));
System.out.println(query.getQueryString());

Related

Sparql query to read from all named graphs without knowing the names

I am looking to run a SPARQL query over any dataset. We dont know the names of the named graphs in the datasets.
These are lots of documentation and examples of selection from named graphs when you know the name of the named graph/s. There are examples showing listing named graphs.
We are running the Jena from Java so it would be possible to run 2 queries, the first gets the named graphs and we inject these into the 2nd.
But surely you can write a single query that reads from all named graphs when you dont know their names?
Note: we are looking to stay away from using default graph/s as their behaviour seems implementation dependent.
Example:
{
?s foaf:name ?name ;
vCard:nickname ?nickName .
}
If you want the pattern to match within one graph and wish to try each graph, use the GRAPH ?g form.
GRAPH ?g
{ ?s foaf:name ?name ;
vc:nickname ?nickName .
}
If you want to make a query where the pattern matches across named graphs, -- e.g. foaf:name in one graph and vCard:nickname in another, same subject --
then set union default graph tdb2:unionDefaultGraph true then the default graph as seen by the query is the union (actually, RDF merge - no duplicates) of all the named graphs. Use the pattern as originally given.
Fuseki configuration file extract:
:dataset_tdb2 rdf:type tdb2:DatasetTDB2 ;
tdb2:location "DB2" ;
## Optional - with union default for query and update WHERE matching.
tdb2:unionDefaultGraph true ;
.
In code, not Fuseki, the application can use Dataset.getUnionModel().

How to Read Specific Range value of an Object Property

i'm new dealing with Ontologies and finding problems to get my SPARQL Query working , trying to read value of specific Object property that has multiple Ranges Object Property Screenshot
trying this Query Return all Object Properties Execution Result , Protege Visualization
PREFIX ns: <http://www.semanticweb.org/pavilion/ontologies/2017/5/untitled-ontology-66#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT *
WHERE {
ns:star1086 ns:possesses ?z .
}
The Desired Result that i want to read only the desired Range value, Thanks in advance.
I think there is something wrong about your ontology.
Specifying muliple ranges to your predicate creates an intersection. Take the following statement:
?star ns:possesses ?something
Then ?something is a SpectralType and a StarTemperature and a StarCoordinates and a StarName at the same time, which is not what you want.
Instead, you should use unions. Using unions, you can state that the object of a ns:possesses statement can be either a SpectralType or a StarTemperature or a StarCoordinates or a StarName. Then, in your SPARQL query you can write the following to get only statements from a single type.
SELECT * WHERE {
ns:star1086 ns:possesses ?z .
?z a ns:SpectralType .
}
In Protégé, to write a union, open the class expression editor (by clicking on the "plus" next to "Ranges" for instance) and separate the different members with or :
SpectralType or StarTemperature or StarCoordinates or StarName
And click "OK" to create the new range.
Further considerations
Let's take a step a back and look at your ontology.
You should not use a single predicate to store all these information in the first place. Instead, I suggest you use different sub-predicates so that your graphs and queries hold more semantic value.
Furthermore, StarName and Temperature are literal values. You should not use classes for that. Use datatype properties instead.
Here is a Gist you can download and open in Protégé. It contains some sample data so you can try the following SPARQL queries.
PREFIX : <http://www.richarddegenne.com/ontology/astronomy#>
# Get all statements about :star1086
SELECT * WHERE {
:star1086 ?predicate ?object
}
# Get some statement about :star1086
SELECT * WHERE {
VALUES ?predicate {
:hasSpectralType :temperate
}
:star1086 ?predicate ?object
}
# Ask whether a given pattern is true
ASK WHERE {
:star1086 :hasSpectralType :yellowDwarf
}
# Filter stars based on their temperature
# Note: You might want to add more stars with different temperature
# if you want useful results.
SELECT ?star WHERE {
?star :temperature ?temperature
FILTER(?temperature > 5000)
}

Get movie(s) based on book(s) from DBpedia

I am new to SPARQL and trying to fetch a movie adapted from specific book from dbpedia. This is what I have so far:
PREFIX onto: <http://dbpedia.org/ontology/>
SELECT *
WHERE
{
<http://dbpedia.org/page/2001:_A_Space_Odyssey> a ?type.
?type onto:basedOn ?book .
?book a onto:Book
}
I can't get any results. How can I do that?
When using any web resource, and in your case the property :basedOn, you need to make sure that you have declared the right prefix. If you are querying from the DBpedia SPARQL endpoint, then you can directly use dbo:basedOneven without declaring it, as it is among predefined. Alternatively, if you want to use your own, or if you are using another SPARQL client, make sure that whatever short name you choose for this property, you declare the prefix for http://dbpedia.org/ontology/.
Then, first, to get more result you may not restrict the type of the subject of this triple pattern, as there could be movies that actually not type as such. So, a query like this
select distinct *
{
?movie dbo:basedOn ?book .
?book a dbo:Book .
}
will give you lots of good results but not all. For example, the resource from your example will be missing. You can easily check test the available properties between these two resource with a query like this:
select ?p
{
{<http://dbpedia.org/resource/2001:_A_Space_Odyssey_(film)> ?p <http://dbpedia.org/resource/2001:_A_Space_Odyssey> }
UNION
{ <http://dbpedia.org/resource/2001:_A_Space_Odyssey> ?p <http://dbpedia.org/resource/2001:_A_Space_Odyssey_(film)>}
}
You'll get only one result:
http://www.w3.org/2000/01/rdf-schema#seeAlso
(note that the URI is with 'resource', not with 'page')
Then you may search for any path between the two resource, using the method described here, or find a combination of other patterns that would increase the number of results.

Marklogic: How can we perform the case-insensitve search in a pure SPARQL query?

I have a scenario where i am trying to find the content using the SPARQL query for the triples stored in marklogic. The filter condition in SPARQL query needs to perform the case-insensitve search for a particular term. May i know how can i do that?
For eg:
filter(strstarts(?personName, "FA"^^xs:string))
The above filters should fetch me the results whose personName value starts with upperCase also(like: fa). I think this will clearly give some idea about the issue i am asking about.
I believe you have two options to do case-insensitive search using SPARQL in MarkLogic.
If you want to use SPARQL only than you can do the following (modify the select statement as needed):
select * where {
?personName ?p ?o
FILTER (lcase(str(?personName)) = "fa"^^xs:string)
}
As an alternative you could also mix some fn:* functions with your SPARQL statement so you could do something similar to:
prefix fn: <http://www.w3.org/2005/xpath-functions#>
select * where {
?personName ?p ?o
FILTER (?personName, fn:lower-case("FA"))
}
Don't forget that in MarkLogic you can use any fn:* or cts:* function as well (the prefix for cts:* functions would be prefix cts: <http://marklogic.com/cts#>
I hope this helps.
Next to the good suggestions of Tamas, there is also REGEX. It accepts a case-insensitivity flag. Something like:
select * where {
?personName ?p ?o
FILTER( regex(str(?personName), "^fa", "i") )
}
HTH!

com.hp.hpl.jena.query.QueryParseException:Unresolved prefixed name

Firstly, I found this relevant question and answer:
Unresolved prefixed name: rdfs:subClassOf in SPARQL query
If I add the PREFIX in the SPARQL query it works. However, I don't want to duplicate all the prefixes in all my SPARQL queries, but to define them only once. I tried to do it programmatically for rdfs::
model.setNsPrefix("rdfs", "http://www.w3.org/2000/01/rdf-schema#");
query.setPrefix("rdfs", "http://www.w3.org/2000/01/rdf-schema#");
and it works, but if I try to do it with my own ontologies it doesn't work:
model.setNsPrefix("myOnt", "http://example.com/ontologies/myOnt#");
query.setPrefix("myOnt", "http://example.com/ontologies/myOnt#");
You can set up a Prologue to contain you prefix mappings and then pass that into the QueryFactory with your specific SPARQL query.
Something like the following worked for me using Apache Jena 3.0.0:
Prologue queryPrologue = new Prologue();
queryPrologue.setPrefix("skos", "http://www.w3.org/2004/02/skos/core#");
String sparql = "SELECT (COUNT ?s) WHERE { ?s a skos:Concept . }"
Query query = QueryFactory.parse(new Query(queryPrologue), sparql, null, null);
try(QueryExecution queryExec = QueryExecutionFactory.create(query, dataset)) {
// ...
}