0
# SPARQL Querying
1
2
Ontospy provides comprehensive SPARQL query capabilities for programmatic ontology interrogation and analysis. The SPARQL helper system offers both direct query execution and specialized methods for common ontological analysis patterns.
3
4
## Capabilities
5
6
### Direct SPARQL Execution
7
8
Execute SPARQL queries directly against loaded RDF graphs or remote SPARQL endpoints.
9
10
```python { .api }
11
# Main Ontospy class query methods
12
def query(self, sparql_query):
13
"""
14
Execute SPARQL query against loaded RDF graph.
15
16
Parameters:
17
- sparql_query (str): SPARQL query string
18
19
Returns:
20
rdflib.plugins.sparql.processor.SPARQLResult: Query results with iteration support
21
"""
22
23
def sparql(self, sparql_query):
24
"""Alias for query() method providing SPARQL execution."""
25
```
26
27
**Usage Examples:**
28
29
```python
30
import ontospy
31
32
# Load ontology
33
g = ontospy.Ontospy("ontology.owl", build_all=True)
34
35
# Simple SELECT query
36
results = g.query("""
37
SELECT ?class ?label WHERE {
38
?class a rdfs:Class .
39
OPTIONAL { ?class rdfs:label ?label }
40
}
41
LIMIT 10
42
""")
43
44
# Process results
45
for row in results:
46
print(f"Class: {row.class}, Label: {row.label}")
47
48
# COUNT query
49
count_result = g.query("""
50
SELECT (COUNT(?class) as ?classCount) WHERE {
51
?class a rdfs:Class
52
}
53
""")
54
55
for row in count_result:
56
print(f"Total classes: {row.classCount}")
57
58
# CONSTRUCT query
59
graph_result = g.query("""
60
CONSTRUCT { ?class rdfs:subClassOf ?parent } WHERE {
61
?class rdfs:subClassOf ?parent .
62
?class a rdfs:Class .
63
?parent a rdfs:Class
64
}
65
""")
66
67
# Resulting graph can be serialized
68
print(graph_result.serialize(format="turtle"))
69
```
70
71
### SPARQL Helper Class
72
73
Specialized helper class providing optimized queries for common ontological analysis patterns.
74
75
```python { .api }
76
from ontospy.core.sparql_helper import SparqlHelper
77
78
class SparqlHelper:
79
def __init__(self, rdfgraph, sparql_endpoint=False):
80
"""
81
Initialize SPARQL helper for ontology analysis.
82
83
Parameters:
84
- rdfgraph (rdflib.Graph): RDF graph to query
85
- sparql_endpoint (bool): Flag indicating remote endpoint usage
86
"""
87
```
88
89
### Ontology Structure Queries
90
91
Extract ontology declarations and metadata using specialized query methods.
92
93
```python { .api }
94
def getOntology(self):
95
"""
96
Extract ontology instances and declarations.
97
98
Returns:
99
list: Ontology URIs and associated metadata
100
"""
101
```
102
103
### Class Analysis Queries
104
105
Comprehensive class analysis including hierarchy extraction, instance counting, and relationship mapping.
106
107
```python { .api }
108
def getAllClasses(self, hide_base_schemas=True, hide_implicit_types=True):
109
"""
110
Extract all class definitions from ontology.
111
112
Parameters:
113
- hide_base_schemas (bool): Filter out base vocabulary (RDF, RDFS, OWL)
114
- hide_implicit_types (bool): Filter implicit type declarations
115
116
Returns:
117
list: Class URIs with metadata
118
"""
119
120
def getClassInstances(self, aURI):
121
"""
122
Get all instances of specified class.
123
124
Parameters:
125
- aURI (str): Class URI
126
127
Returns:
128
list: Instance URIs that are members of the class
129
"""
130
131
def getClassInstancesCount(self, aURI):
132
"""
133
Count instances of specified class.
134
135
Parameters:
136
- aURI (str): Class URI
137
138
Returns:
139
int: Number of class instances
140
"""
141
142
def getClassDirectSupers(self, aURI):
143
"""
144
Get immediate superclasses of specified class.
145
146
Parameters:
147
- aURI (str): Class URI
148
149
Returns:
150
list: Direct parent class URIs
151
"""
152
153
def getClassDirectSubs(self, aURI):
154
"""
155
Get immediate subclasses of specified class.
156
157
Parameters:
158
- aURI (str): Class URI
159
160
Returns:
161
list: Direct child class URIs
162
"""
163
164
def getClassAllSupers(self, aURI):
165
"""
166
Get all superclasses (transitive closure).
167
168
Parameters:
169
- aURI (str): Class URI
170
171
Returns:
172
list: All ancestor class URIs
173
"""
174
175
def getClassAllSubs(self, aURI):
176
"""
177
Get all subclasses (transitive closure).
178
179
Parameters:
180
- aURI (str): Class URI
181
182
Returns:
183
list: All descendant class URIs
184
"""
185
```
186
187
### Property Analysis Queries
188
189
Extract property definitions, hierarchies, and domain/range relationships.
190
191
```python { .api }
192
def getAllProperties(self, hide_implicit_preds=True):
193
"""
194
Extract all property definitions.
195
196
Parameters:
197
- hide_implicit_preds (bool): Filter implicit predicate declarations
198
199
Returns:
200
list: Property URIs with type information
201
"""
202
203
def getPropDirectSupers(self, aURI):
204
"""
205
Get immediate superproperties.
206
207
Parameters:
208
- aURI (str): Property URI
209
210
Returns:
211
list: Direct parent property URIs
212
"""
213
214
def getPropAllSupers(self, aURI):
215
"""
216
Get all superproperties (transitive closure).
217
218
Parameters:
219
- aURI (str): Property URI
220
221
Returns:
222
list: All ancestor property URIs
223
"""
224
225
def getPropAllSubs(self, aURI):
226
"""
227
Get all subproperties (transitive closure).
228
229
Parameters:
230
- aURI (str): Property URI
231
232
Returns:
233
list: All descendant property URIs
234
"""
235
236
def getPropsApplicableByShapes(self):
237
"""
238
Get properties constrained by SHACL shapes.
239
240
Returns:
241
list: Properties with SHACL shape constraints
242
"""
243
```
244
245
### SKOS Concept Queries
246
247
Analyze SKOS concept schemes, hierarchies, and broader/narrower relationships.
248
249
```python { .api }
250
def getSKOSInstances(self):
251
"""
252
Extract all SKOS concept instances.
253
254
Returns:
255
list: SKOS concept URIs with scheme information
256
"""
257
258
def getSKOSDirectSupers(self, aURI):
259
"""
260
Get broader concepts (immediate parents).
261
262
Parameters:
263
- aURI (str): SKOS concept URI
264
265
Returns:
266
list: Direct broader concept URIs
267
"""
268
269
def getSKOSDirectSubs(self, aURI):
270
"""
271
Get narrower concepts (immediate children).
272
273
Parameters:
274
- aURI (str): SKOS concept URI
275
276
Returns:
277
list: Direct narrower concept URIs
278
"""
279
```
280
281
### SHACL Shape Queries
282
283
Extract SHACL shape definitions and constraint specifications.
284
285
```python { .api }
286
def getShapes(self):
287
"""
288
Extract all SHACL shape definitions.
289
290
Returns:
291
list: SHACL shape URIs with constraint metadata
292
"""
293
```
294
295
### Entity Metadata Queries
296
297
Extract detailed metadata and triple information for specific entities.
298
299
```python { .api }
300
def entityTriples(self, aURI):
301
"""
302
Get all RDF triples for specified entity.
303
304
Parameters:
305
- aURI (str): Entity URI
306
307
Returns:
308
list: RDF triples as (subject, predicate, object) tuples
309
"""
310
```
311
312
## Advanced Query Patterns
313
314
### Complex Analysis Workflows
315
316
```python
317
import ontospy
318
from ontospy.core.sparql_helper import SparqlHelper
319
320
# Load ontology
321
g = ontospy.Ontospy("ontology.owl", build_all=True)
322
323
# Create SPARQL helper
324
helper = SparqlHelper(g.rdflib_graph)
325
326
# Analyze class hierarchy depth
327
classes = helper.getAllClasses()
328
for class_uri in classes:
329
supers = helper.getClassAllSupers(class_uri)
330
subs = helper.getClassAllSubs(class_uri)
331
instances = helper.getClassInstancesCount(class_uri)
332
333
print(f"Class: {class_uri}")
334
print(f" Ancestors: {len(supers)}")
335
print(f" Descendants: {len(subs)}")
336
print(f" Instances: {instances}")
337
338
# Property usage analysis
339
properties = helper.getAllProperties()
340
for prop_uri in properties:
341
# Custom SPARQL to find domain/range usage
342
domain_query = f"""
343
SELECT DISTINCT ?domain WHERE {{
344
<{prop_uri}> rdfs:domain ?domain
345
}}
346
"""
347
domains = g.query(domain_query)
348
349
range_query = f"""
350
SELECT DISTINCT ?range WHERE {{
351
<{prop_uri}> rdfs:range ?range
352
}}
353
"""
354
ranges = g.query(range_query)
355
356
print(f"Property: {prop_uri}")
357
print(f" Domains: {[str(row.domain) for row in domains]}")
358
print(f" Ranges: {[str(row.range) for row in ranges]}")
359
```
360
361
### SPARQL Endpoint Integration
362
363
```python
364
import ontospy
365
366
# Connect to remote SPARQL endpoint
367
g = ontospy.Ontospy(
368
sparql_endpoint="http://dbpedia.org/sparql",
369
build_all=False # Don't build locally, query remotely
370
)
371
372
# Query remote endpoint
373
results = g.query("""
374
PREFIX dbo: <http://dbpedia.org/ontology/>
375
SELECT ?person ?name ?birthPlace WHERE {
376
?person a dbo:Person ;
377
foaf:name ?name ;
378
dbo:birthPlace ?birthPlace .
379
FILTER(LANG(?name) = "en")
380
}
381
LIMIT 10
382
""")
383
384
for row in results:
385
print(f"Person: {row.name}, Born: {row.birthPlace}")
386
387
# Use SPARQL helper with endpoint
388
helper = SparqlHelper(g.rdflib_graph, sparql_endpoint=True)
389
# Note: Some helper methods may not work with remote endpoints
390
```
391
392
### Custom Query Development
393
394
```python
395
def find_classes_with_instances(g, min_instances=1):
396
"""Find classes that have at least N instances."""
397
query = f"""
398
SELECT ?class (COUNT(?instance) as ?count) WHERE {{
399
?class a rdfs:Class .
400
?instance a ?class
401
}}
402
GROUP BY ?class
403
HAVING(COUNT(?instance) >= {min_instances})
404
ORDER BY DESC(?count)
405
"""
406
return g.query(query)
407
408
def analyze_property_chains(g):
409
"""Find potential property chain patterns."""
410
query = """
411
SELECT ?prop1 ?prop2 ?common WHERE {
412
?x ?prop1 ?common .
413
?common ?prop2 ?y .
414
?prop1 a rdf:Property .
415
?prop2 a rdf:Property .
416
FILTER(?prop1 != ?prop2)
417
}
418
GROUP BY ?prop1 ?prop2 ?common
419
"""
420
return g.query(query)
421
422
def find_orphaned_classes(g):
423
"""Find classes with no superclasses or subclasses."""
424
query = """
425
SELECT DISTINCT ?class WHERE {
426
?class a rdfs:Class .
427
FILTER NOT EXISTS { ?class rdfs:subClassOf ?super }
428
FILTER NOT EXISTS { ?sub rdfs:subClassOf ?class }
429
}
430
"""
431
return g.query(query)
432
433
# Usage
434
g = ontospy.Ontospy("ontology.owl", build_all=True)
435
436
popular_classes = find_classes_with_instances(g, min_instances=10)
437
for row in popular_classes:
438
print(f"Class {row.class} has {row.count} instances")
439
440
orphaned = find_orphaned_classes(g)
441
print(f"Found {len(list(orphaned))} orphaned classes")
442
```
443
444
## Query Optimization and Best Practices
445
446
### Performance Considerations
447
448
```python
449
# Use LIMIT for large result sets
450
results = g.query("""
451
SELECT ?s ?p ?o WHERE {
452
?s ?p ?o
453
}
454
LIMIT 1000
455
""")
456
457
# Use COUNT for statistics rather than retrieving all results
458
count_query = g.query("""
459
SELECT (COUNT(*) as ?total) WHERE {
460
?s a rdfs:Class
461
}
462
""")
463
464
# Use OPTIONAL for optional properties
465
results = g.query("""
466
SELECT ?class ?label ?comment WHERE {
467
?class a rdfs:Class .
468
OPTIONAL { ?class rdfs:label ?label }
469
OPTIONAL { ?class rdfs:comment ?comment }
470
}
471
""")
472
```
473
474
### Common Query Templates
475
476
```python
477
# Template for hierarchy analysis
478
HIERARCHY_TEMPLATE = """
479
SELECT ?entity ?parent WHERE {{
480
?entity rdfs:subClassOf* ?parent .
481
?entity a {entity_type} .
482
?parent a {entity_type}
483
}}
484
"""
485
486
# Template for property analysis
487
PROPERTY_USAGE_TEMPLATE = """
488
SELECT ?prop (COUNT(?usage) as ?count) WHERE {{
489
?s ?prop ?o .
490
?prop a {property_type}
491
}}
492
GROUP BY ?prop
493
ORDER BY DESC(?count)
494
"""
495
496
# Usage
497
class_hierarchy = g.query(
498
HIERARCHY_TEMPLATE.format(entity_type="rdfs:Class")
499
)
500
501
object_prop_usage = g.query(
502
PROPERTY_USAGE_TEMPLATE.format(property_type="owl:ObjectProperty")
503
)
504
```