SPARQL query on Protege for Number of Classes - sparql

In order to determine the number of classes in a .owl file,
I was advised to use the following SPARQL query:
SELECT ( count(?class) as ?count )
WHERE { graph <put_your_model_graph_name_here> { ?class a owl:Class . } }
However, when I replace the put_your_model_graph_name_here with my ontology IRI, I get 0
I also tried http://blahblahblah followed immediately by # to no avail.
What am I doing wrong?

Difficult to tell without seeing how you are loading and querying the data. Try using:
SELECT ( count(?class) as ?count ) { ?class a owl:Class }
which will query the default graph, or
SELECT ?g ( count(?class) as ?count )
{ graph ?g { ?class a owl:Class } }
group by ?g
which will give counts for all the named graphs.

Related

How to list root classes of an ontology in SPARQL?

I am trying to list root classes of the NIF ontology which is an ontology created of several other ontologies as its modules.
I use this code from an online resource:
SELECT ?directSub ?super
WHERE { ?directSub rdfs:subClassOf ?super .
FILTER NOT EXISTS {
?directSub rdfs:subClassOf ?otherSub .
FILTER (?otherSub != ?directSub)
}
}
The logic of the code seems fine but it does not return any answers (even when I test it on other ontologies)! Why is that?
The #UninformedUser's answer works fine. However, there is an exception that does not work with that solution, which is a root class without any child. The solution assumes that all roots have subclasses, which is not always true.
The following piece of code can find these classes:
SELECT DISTINCT ?exClass
WHERE {
?exClass rdf:type owl:Class
FILTER NOT EXISTS { ?subClass rdfs:subClassOf ?exClass }
FILTER NOT EXISTS { ?exClass rdfs:subClassOf ?supClass }}
Hence, the full SPARQL query for finding all root nodes is:
SELECT DISTINCT ?rootClass
WHERE {{
?rootClass rdf:type owl:Class .
?subClass rdf:type owl:Class .
?subClass rdfs:subClassOf ?rootClass
FILTER NOT EXISTS {
?rootClass rdfs:subClassOf ?otherSup
FILTER (?otherSup != owl:Thing)}
} UNION {
?rootClass rdf:type owl:Class
FILTER NOT EXISTS { ?subClass rdfs:subClassOf ?rootClass }
FILTER NOT EXISTS { ?rootClass rdfs:subClassOf ?supClass }}}
I am sure that the above pieces of code can be improved, however, I am just a beginner. I really would appreciate it if someone can provide tips on how to improve it.

insert from two named graphs?

I'm looking for an easy way to insert triples from two or more named graphs (but not the entire unnamed default graph) into another named graph. I'm using GraphDB.
I guess this could be done by writing out the same query multiple times in the WHERE section, wrapped in multiple GRAPH specifications, and then unioning them together, but my WHEREs are long and I'd prefer not to write them out multiple times.
Let's say I have loaded some data like this:
INSERT DATA {
GRAPH <http://example.com/ngA> {
<http://example.com/person1> <http://example.com/name> "Arthur" .
}
GRAPH <http://example.com/ngB> {
<http://example.com/person1> <http://example.com/name> "Brian" .
}
GRAPH <http://example.com/ngC> {
<http://example.com/person1> <http://example.com/name> "Charlie" .
}
}
I can copy all of the triples of a certain pattern from the default unnamed graph into a new named graph with something like this:
INSERT {
GRAPH <http://example.com/ngZ> {
?s <http://example.com/moniker> ?o .
}
}
WHERE
{ ?s <http://example.com/name> ?o }
An easy way to SELECT for triples of a given pattern from two or more (but not all) named graphs is
SELECT *
FROM <http://example.com/ngA>
FROM <http://example.com/ngB>
WHERE
{ ?s <http://example.com/name> ?o }
What if I want to copy those triples, from those specified graphs, into another graph?
I'm getting an error from GraphDB 8.3 (and from the sparql.org validator) when I try to
INSERT {
GRAPH <http://example.com/ngZ> {
?s <http://example.com/moniker> ?o .
}
}
WHERE
{ SELECT *
FROM <http://example.com/ngA>
FROM <http://example.com/ngB>
WHERE
{ ?s <http://example.com/name> ?o } }
Try this query:
PREFIX ex: <http://example.com/>
INSERT {
GRAPH ex:ngZ { ?s ex:moniker ?o }
}
WHERE {
GRAPH ?g { ?s ex:name ?o }
FILTER (?g IN ( ex:ngA, ex:ngB ) )
}
And then:
PREFIX ex: <http://example.com/>
SELECT *
FROM NAMED ex:ngZ
WHERE {
GRAPH ?g { ?s ?p ?o }
} LIMIT 100
Is it what you need?
By the way, there exist COPY (use with caution!) and ADD.
SPARQL Update provides USING and USING NAMED analogous to FROM and FROM NAMED in queries:
The USING and USING NAMED clauses affect the RDF Dataset used while evaluating the WHERE clause. This describes a dataset in the same way as FROM and FROM NAMED clauses
You can express the requirement as an UPDATE like so:
INSERT {
GRAPH <http://example.com/ngZ> {
?s <http://example.com/moniker> ?o .
}
}
USING <http://example.com/ngA>
USING <http://example.com/ngB>
WHERE
{ ?s <http://example.com/name> ?o }
Also note that, according to the SPARQL query grammar, a subquery does not admit a dataset clause. This is why the SPARQL parsers are rejecting your query.
Thanks, #Stanislav Kralin
Come to think of it, this also works:
PREFIX ex: <http://example.com/>
INSERT {
GRAPH ex:ngZ {
?s ex:moniker ?o
}
}
WHERE {
values ?g {
ex:ngA ex:ngB
}
GRAPH ?g {
?s ex:name ?o
}
}

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

Incomplete sem:sparql results for Property Paths when "optimize=0"

Consider the following subClassOf relations:
m1
|_ m1_1
|_ m1_1_1
The following query correctly returns m1_1 and m1_1_1:
sem:sparql('
SELECT *
WHERE {
?s <http://www.w3.org/2000/01/rdf-schema#subClassOf>+ <http://example.org/people#m1> .
}', (),
("optimize=1"))
However, the following query only returns m1_1:
sem:sparql('
SELECT *
WHERE {
?s <http://www.w3.org/2000/01/rdf-schema#subClassOf>+ <http://example.org/people#m1> .
}', (),
("optimize=0"))
It's also the case with *.
After upgrading to MarkLogic 8.0-5.2, the previous sem:sparql queries return correct results but not when the object is a parameter. E.g. the following query doesn't return anything:
sem:sparql('
SELECT *
WHERE {
?s <http://www.w3.org/2000/01/rdf-schema#subClassOf>+ ?item .
}',
(map:new ((map:entry ("item", sem:iri("http://example.org/people#m1"))))),
("optimize=0"))
Here are some possible workarounds:
sem:sparql('
SELECT *
WHERE {
BIND (?param AS ?item) .
?s <http://www.w3.org/2000/01/rdf-schema#subClassOf>+ ?item .
}',
(map:new ((map:entry ("param", sem:iri("http://example.org/people#m1"))))),
("optimize=0"))
Or
sem:sparql('
SELECT *
WHERE {
?s <http://www.w3.org/2000/01/rdf-schema#subClassOf>+ ?item .
FILTER (?item = ?param) .
}',
(map:new ((map:entry ("param", sem:iri("http://example.org/people#m1"))))),
("optimize=0"))
Checking with a a fairly complex RDFS ontology using MarkLogic 8.0-5.2, this seems to work OK. Is it possible to upgrade? There was some significant semantics work around 8.0-4.0.

Select inside another select

I have the following query where I'm trying to use the id of an element from one graph to retrieve some values in another graph. However this doesn't work:
select * from <mygraph2#> where {
?s ?p ?id in {select ?id from <mygraph1#> where { ?id ?t "MyService" }
}
You don't select from a subselect. You just execute the sub-select, and it provides some variables to the enclosing query. I'm not sure where you found an example like what you showed in the question. It's not what any of the examples in the standard (see Section 12, Subqueries) look like. Your query would be something like this (note that this isn't actually legal, since you can't use FROM in subqueries):
select * from <mygraph2#> where {
?s ?p ?id
{ select ?id from <mygraph1#>
where { ?id ?t "MyService" } }
}
However, the the graphs that you're selecting from are available as named graphs in the dataset, there's no real need for the sub-select here. You can just do
select * where {
graph <mygraph2#> { ?s ?p ?id }
graph <mygraph1#> { ?id ?t "MyService" }
}