To QLever
| To QLever | |
| A SPARQL query converter | |
|---|---|
| Platforms | Web · Bookmarklet |
| Source Code | GitLab |
| Runs on | Toolforge |
| Target endpoint | QLever Wikidata |
To QLever is a Toolforge tool that rewrites SPARQL queries written for the Wikidata Query Service (WDQS) so that they run on QLever, and then links you straight to the result.
Paste a query.wikidata.org link or the query text itself, and the tool hands you back a working QLever query. The source code is at GitLab.
How it works
[edit]WDQS runs on Blazegraph, QLever does not. The two engines disagree about a handful of things, and "To QLever" patches over exactly those.
Not every difference between the two endpoints needs a rewrite. The QLever team maintain their own comparison of the two — see See also below — and much of it is about the data and the UI rather than the query language. Both endpoints serve the whole of Wikidata and both track live edits, so a query that is valid on one is usually a rewrite or two away from running on the other. What genuinely differs is the Blazegraph-only syntax WDQS accepts, which is what this tool removes.
Labels are the clearest example. WDQS is slow at rdfs:label, which is why it offers SERVICE wikibase:label in the first place; QLever queries rdfs:label directly without trouble, provided the query says which language it wants. That is exactly the shape the converter emits.
The converter parses your query into an abstract syntax tree with TRAQULA, a real SPARQL 1.1 parser and generator, rewrites the tree, and serializes it back to text. Working on a tree rather than on raw text means nested groups, comments containing SPARQL-like tokens, and unusual whitespace cannot confuse the rewriter.
Named subqueries are the one exception. Their %name syntax is not SPARQL 1.1 at all, so the parser cannot read them and they are rewritten textually, before parsing. The parser still has the last word on whether the result is valid.
What gets rewritten
[edit]SERVICE wikibase:label- Replaced with one
OPTIONAL { ?x rdfs:label ?xLabel . FILTER(LANG(?xLabel) = "…") }block per fallback language. - Both forms are handled. The auto form derives the
?xLabel,?xAltLabeland?xDescriptionvariables from the query as a whole; the manual form uses the explicit label triples inside the service block.[AUTO_LANGUAGE]is resolved to your configured language preference. - Where the labelled variable is itself bound inside an
OPTIONAL, the label block is placed inside thatOPTIONALrather than after it. This matters far more than it looks: left outside, the block also has to cover the rows where the variable never got bound, and with no binding to join against QLever sorts an enormous intermediate result. The same query nested answers in seconds where it otherwise times out. The results are identical either way.
- Named subqueries (
WITH { … } AS %name/INCLUDE %name) - Inlined: each named block is substituted at every
INCLUDEthat refers to it, becoming an ordinary SPARQL subquery. Blazegraph evaluates a named subquery once and reuses the solutions, while an inlined one is evaluated at each site — with a singleINCLUDE, the usual case, the two are equivalent. On by default; switch it off under Advanced options to have such queries refused instead.
- Long label fallback lists
- Trimmed. The label rewrite costs one
OPTIONALper label variable per language, so a list of seven languages across four label variables becomes 28 blocks — enough for QLever to run out of memory on a query WDQS handles. Above three languages the list is cut to the query's own first choice (usually[AUTO_LANGUAGE], the reader's language), thenen, thenmul, Wikidata's language-neutral label. Shorter lists are never touched, and never padded. On by default; switch it off under Advanced options to keep every language.
- Blazegraph query hints (
hint:…) - Removed. QLever does not support them, and leaving them in causes parse errors.
- Blazegraph-only prefix declarations (
bd:,hint:) - Stripped from the output.
- Missing prefix declarations
- Added. The WDQS editor silently injects the standard Wikidata prefixes for you; QLever's raw endpoint does not. Every prefix the query uses is therefore declared explicitly in the output.
- Unsupported services (
wikibase:mwapi,wikibase:around,wikibase:box) - Left unchanged, with a warning. These need Blazegraph-specific extensions that QLever cannot run.
- Coordinate columns
- When a
SELECTprojects a variable bound to a globe coordinate (any Wikidata coordinate property, such aswdt:P625), that column is moved to the end. QLever's Map View is offered when the last column holds something mappable, so without this an otherwise fine query loses its map. On by default; switch it off under Advanced options.
- Leading comments
- The WDQS header block (
#title:, a description,#defaultView:…) is copied verbatim to the top of the output.
Whenever one of the optional rewrites above actually changes something, it says so in a # To QLever: comment directly beneath that header, so a converted query still explains itself once it has been pasted somewhere and the tool is out of sight:
#title: 'solved' classes from physical/abstract anomaly list # To QLever: inlined 1 Blazegraph named subquery (%classes) # To QLever: label fallback languages limited to fr, en, mul (query asked for en, mul, fr, de, es, it, sv) PREFIX wd: <http://www.wikidata.org/entity/> …
Bookmarklet
[edit]The home page offers a draggable bookmarklet. Drag it to your bookmarks bar once. From then on, one click while you are viewing any query on query.wikidata.org opens the converted QLever version.
The bookmarklet simply navigates to https://to-qlever.toolforge.org/to-qlever?url=<current URL>. The conversion happens server-side, and you are redirected to QLever. Nothing is injected into the WDQS page, so none of that UI's constraints apply, and no browser extension is needed.
Notes and limitations
[edit]- The label rewrite only approximates WDQS fallback semantics, using ordered
OPTIONALandFILTER(LANG(...))blocks. It labels the entity bound to the base variable —?itemfor?itemLabel. Labelling properties would also need a?prop wikibase:directClaim ?ptriple, which is not added automatically. - The language match is exact, so a label tagged
en-gbdoes not answer a request foren. WDQS's own fallback is looser, and a converted query can therefore return fewer labels than the original. - Label blocks are placed where QLever can afford them: nested inside the
OPTIONALthat binds the variable where one clearly owns it, otherwise below the patterns that bind it. A block whose label variable is read elsewhere in the same group — by aFILTERorBIND— stays where the service was, which is correct but can be slow. Moving it by hand is worth trying if a converted query times out. - A
?xLabelthe query binds itself is left to the query, as WDQS leaves it; one whose?xappears nowhere is dropped with a warning rather than converted into a scan of every label in Wikidata. - Only the first auto-mode label service in a query is expanded. A second one, and the languages it asks for, are silently ignored.
- A label service written inside a subquery labels inside that subquery. Unless the subquery's own
SELECTprojects the label variable, the column comes back empty. SERVICE wdsubgraph:...is removed: QLever indexes the scholarly and main subgraphs together, so there is nothing to federate with. Where the WDQS internal-federation idiom put the same pattern on both sides of aUNION, the two arms are folded back into one; where the arms differ, the conversion warns that rows may now be duplicated.- Hand-built WKT strings passed to
geof:functions are wrapped inSTRDT(..., geo:wktLiteral). Blazegraph accepts a plain string there and QLever does not — it returns unbound instead, which silently empties the result through whateverFILTERreads it. Other geospatial differences, including replacements forwikibase:aroundandwikibase:box, are not written for you. - QLever's stricter
GROUP BYhandling and its numeric-literal quirks are not addressed. Queries that lean on WDQS being lenient here may still need a manual fix. - Only the leading comment block survives. Comments in the middle of the query body cannot be preserved: the SPARQL parser discards comment tokens while building the tree, leaving no node to re-attach them to.
See also
[edit]- Differences between QLever's Wikidata SPARQL endpoint and the Wikidata Query Service (WDQS) — the QLever team's own comparison: dataset extent and actuality, labels, sitelinks, efficiency and the two user interfaces. Useful background for anything this converter does not handle.
- QLever's Wikidata endpoint — where converted queries end up.
- query.wikidata.org — the Wikidata Query Service itself.