You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 40354a7
Browse filesBrowse the repository at this point in the historyBrowse files
feat(gravsearch): improve gravsearch performance by using unions in prequery (DEV-492) (#2045)
* Update SparqlTransformer.scala
* feat: add superPropertyOf map to ontology cache
* refactor: reduce logging noise
* chore: add clean-sbt target to makefile
* feat: replace property path query statements with unions for subPropertyOf*
* feat: use unions for subclasses
* refactor: tidy up some old mess
* refactor: add more logging
* add limiting param to transformer to reduce inference
* ignore failing test for now
* feat: start working on reducing union options on basis of the query
* tidy up
* minor improvements
* get tests to pass
* feat: limit subclasses
* feat: include optimization in count query
* test: minimal test for compound objects with gravsearch
* test: test simulated inference with union patterns
* refactor start tidying up
* refactor: more tidying up
* refactor: tidy up
* docs: start documenting the changes
* refactor: remove unused code
* docs: update documentation
* refactor: remove some code smells
* refactor: tidy up, improve variable naming and add documentation
* refactor: format sparqlTransformarSpec.scala
* Apply suggestions from code review
Co-authored-by: irinaschubert <irina.schubert@dasch.swiss>
* tidy up
* wrap up according to review
Co-authored-by: irinaschubert <irina.schubert@dasch.swiss>
It also has the benefit of enabling clients to work with a simpler RDF
16
-
data model than the one Knora actually uses to store data in the
16
+
data model than the one the API actually uses to store data in the
17
17
triplestore, and makes it possible to provide better error-checking.
18
18
19
19
Rather than being processed directly by the triplestore, a Gravsearch query
20
-
is interpreted by Knora, which enforces certain
20
+
is interpreted by the API, which enforces certain
21
21
restrictions on the query, and implements paging and permission
22
22
checking. The API server generates SPARQL based on the Gravsearch query
23
23
submitted, queries the triplestore, filters the results according to the
24
-
user's permissions, and returns each page of query results as a Knora
24
+
user's permissions, and returns each page of query results as an
25
25
API response. Thus, Gravsearch is a hybrid between a RESTful API and a
26
26
SPARQL endpoint.
27
27
@@ -80,14 +80,14 @@ If a gravsearch query times out, a `504 Gateway Timeout` will be returned.
80
80
A Gravsearch query can be written in either of the two
81
81
[DSP-API v2 schemas](introduction.md#api-schema). The simple schema
82
82
is easier to work with, and is sufficient if you don't need to query
83
-
anything below the level of a Knora value. If your query needs to refer to
83
+
anything below the level of a DSP-API value. If your query needs to refer to
84
84
standoff markup, you must use the complex schema. Each query must use a single
85
85
schema, with one exception (see [Date Comparisons](#date-comparisons)).
86
86
87
87
Gravsearch query results can be requested in the simple or complex schema;
88
88
see [API Schema](introduction.md#api-schema).
89
89
90
-
All examples hereafter run with Knora started locally as documented in the section [Getting Started with DSP-API](../../04-publishing-deployment/getting-started.md). If you access another Knora-Stack, you can check the IRI of the ontology you are targeting by requesting the [ontologies metadata](ontology-information.md#querying-ontology-metadata).
90
+
All examples hereafter run with the DSP stack started locally as documented in the section [Getting Started with DSP-API](../../04-publishing-deployment/getting-started.md). If you access another stack, you can check the IRI of the ontology you are targeting by requesting the [ontologies metadata](ontology-information.md#querying-ontology-metadata).
Copy file name to clipboardExpand all lines: docs/05-internals/design/api-v2/gravsearch.md
+13-34Lines changed: 13 additions & 34 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -128,7 +128,7 @@ pattern orders must be optimised by moving `LuceneQueryPatterns` to the beginnin
128
128
-`ConstructToConstructTransformer` (extends `WhereTransformer`): instructions how to turn a triplestore independent Construct query into a triplestore dependent Construct query (implementation of inference).
129
129
130
130
The traits listed above define methods that are implemented in the transformer classes and called by `QueryTraverser` to perform SPARQL to SPARQL conversions.
131
-
When iterating over the statements of the input query, the transformer class's transformation methods are called to perform the conversion.
131
+
When iterating over the statements of the input query, the transformer class' transformation methods are called to perform the conversion.
132
132
133
133
### Prequery
134
134
@@ -152,7 +152,7 @@ Next, the Gravsearch query's WHERE clause is transformed and the prequery (SELEC
152
152
The transformation of the Gravsearch query's WHERE clause relies on the implementation of the abstract class `AbstractPrequeryGenerator`.
153
153
154
154
`AbstractPrequeryGenerator` contains members whose state is changed during the iteration over the statements of the input query.
155
-
They can then by used to create the converted query.
155
+
They can then be used to create the converted query.
156
156
157
157
-`mainResourceVariable: Option[QueryVariable]`: SPARQL variable representing the main resource of the input query. Present in the prequery's SELECT clause.
158
158
-`dependentResourceVariables: mutable.Set[QueryVariable]`: a set of SPARQL variables representing dependent resources in the input query. Used in an aggregation function in the prequery's SELECT clause (see below).
@@ -288,29 +288,12 @@ to the maximum allowed page size, the predicate
288
288
289
289
## Inference
290
290
291
-
Gravsearch queries support a subset of RDFS reasoning
292
-
(see [Inference](../../../03-apis/api-v2/query-language.md#inference) in the API documentation
291
+
Gravsearch queries support a subset of RDFS reasoning (see [Inference](../../../03-apis/api-v2/query-language.md#inference) in the API documentation
293
292
on Gravsearch). This is implemented as follows:
294
293
295
-
When the non-triplestore-specific version of a SPARQL query is generated, statements that do not need
296
-
inference are marked with the virtual named graph `<http://www.knora.org/explicit>`.
294
+
To simulate RDF inference, the API expands the prequery on basis of the available ontologies. For that reason, `SparqlTransformer.transformStatementInWhereForNoInference` expands all `rdfs:subClassOf` and `rdfs:subPropertyOf`statements using `UNION` statements for all subclasses and subproperties from the ontologies (equivalent to `rdfs:subClassOf*` and `rdfs:subPropertyOf*`).
When the triplestore-specific version of the query is generated:
299
-
300
-
- If the triplestore is GraphDB, `SparqlTransformer.transformKnoraExplicitToGraphDBExplicit` changes statements
301
-
with the virtual graph `<http://www.knora.org/explicit>` so that they are marked with the GraphDB-specific graph
302
-
`<http://www.ontotext.com/explicit>`, and leaves other statements unchanged.
303
-
`SparqlTransformer.transformKnoraExplicitToGraphDBExplicit` also adds the `valueHasString` statements which GraphDB needs
304
-
for text searches.
305
-
306
-
- If Knora is not using the triplestore's inference (e.g. with Fuseki),
307
-
`SparqlTransformer.transformStatementInWhereForNoInference` removes `<http://www.knora.org/explicit>`, and expands unmarked
308
-
statements using `rdfs:subClassOf*` and `rdfs:subPropertyOf*`.
309
-
310
-
Gravsearch also provides some virtual properties, which take advantage of forward-chaining inference
311
-
as an optimisation if the triplestore provides it. For example, the virtual property
312
-
`knora-api:standoffTagHasStartAncestor` is equivalent to `knora-base:standoffTagHasStartParent*`. If Knora is not using the triplestore's inference, `SparqlTransformer.transformStatementInWhereForNoInference`
313
-
replaces `knora-api:standoffTagHasStartAncestor` with `knora-base:standoffTagHasStartParent*`.
314
297
315
298
# Optimisation of generated SPARQL
316
299
@@ -320,8 +303,7 @@ Lucene queries to the beginning of the block in which they occur.
320
303
321
304
## Query Optimization by Topological Sorting of Statements
322
305
323
-
GraphDB seems to have inherent algorithms to optimize the query time, however query performance of Fuseki highly depends
324
-
on the order of the query statements. For example, a query such as the one below:
306
+
In Jena Fuseki, the performance of a query highly depends on the order of the query statements. For example, a query such as the one below:
@@ -370,8 +352,7 @@ The rest of the query then reads:
370
352
?letter beol:creationDate ?date .
371
353
```
372
354
373
-
Since we cannot expect clients to know about performance of triplestores in order to write efficient queries, we have
374
-
implemented an optimization method to automatically rearrange the statements of the given queries.
355
+
Since users cannot be expected to know about performance of triplestores in order to write efficient queries, an optimization method to automatically rearrange the statements of the given queries has been implemented.
375
356
Upon receiving the Gravsearch query, the algorithm converts the query to a graph. For each statement pattern,
376
357
the subject of the statement is the origin node, the predicate is a directed edge, and the object
377
358
is the target node. For the query above, this conversion would result in the following graph:
0 commit comments