How does one get a SPARQL 1.1 alternative for SERVICE labeling with Wikidata Query Service (or another SPARQL endpoint with data from Wikidata) with fallback?
I am thinking about the alternative to this query
SELECT
?item ?itemLabel
WHERE {
BIND(wd:Q133262867 AS ?item)
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],mul,en,da". }
}
The part with [AUTO_LANGUAGE]
seems not to be possible in standard SPARQL without an interpolation. I suppose?
For the fallback labeling for the rest of the languages ('mul', 'en', 'da'), the pattern I can think of would be one with multiple OPTIONALs and a COALESCE like
SELECT
?item ?itemLabel
WHERE {
BIND(wd:Q133262867 AS ?item)
OPTIONAL {
?item rdfs:label ?label_mul .
FILTER (LANG(?label_mul) = 'mul')
}
OPTIONAL {
?item rdfs:label ?label_en .
FILTER (LANG(?label_en) = 'en')
}
OPTIONAL {
?item rdfs:label ?label_da .
FILTER (LANG(?label_da) = 'da')
}
BIND(COALESCE(?label_mul, ?label_en, ?label_da) AS ?itemLabel)
}
This patterns looks inefficient and verbose. It becomes even more elaborate if we want the description along and more languages
SELECT
?item ?itemLabel ?itemDescription
WHERE {
BIND(wd:Q133262867 AS ?item)
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],mul,en,cz,da,fr". }
}
... and this is just for one variable.
Would there be any better solution?
How does one get a SPARQL 1.1 alternative for SERVICE labeling with Wikidata Query Service (or another SPARQL endpoint with data from Wikidata) with fallback?
I am thinking about the alternative to this query
SELECT
?item ?itemLabel
WHERE {
BIND(wd:Q133262867 AS ?item)
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],mul,en,da". }
}
The part with [AUTO_LANGUAGE]
seems not to be possible in standard SPARQL without an interpolation. I suppose?
For the fallback labeling for the rest of the languages ('mul', 'en', 'da'), the pattern I can think of would be one with multiple OPTIONALs and a COALESCE like
SELECT
?item ?itemLabel
WHERE {
BIND(wd:Q133262867 AS ?item)
OPTIONAL {
?item rdfs:label ?label_mul .
FILTER (LANG(?label_mul) = 'mul')
}
OPTIONAL {
?item rdfs:label ?label_en .
FILTER (LANG(?label_en) = 'en')
}
OPTIONAL {
?item rdfs:label ?label_da .
FILTER (LANG(?label_da) = 'da')
}
BIND(COALESCE(?label_mul, ?label_en, ?label_da) AS ?itemLabel)
}
This patterns looks inefficient and verbose. It becomes even more elaborate if we want the description along and more languages
SELECT
?item ?itemLabel ?itemDescription
WHERE {
BIND(wd:Q133262867 AS ?item)
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],mul,en,cz,da,fr". }
}
... and this is just for one variable.
Would there be any better solution?
Share Improve this question asked Mar 12 at 15:18 Finn Årup NielsenFinn Årup Nielsen 6,7561 gold badge35 silver badges45 bronze badges2 Answers
Reset to default 1I was just yesterday trying to figure out the same thing. I came up with the following code.
PREFIX rdfs: <http://www.w3./2000/01/rdf-schema#>
PREFIX wd: <http://www.wikidata./entity/>
PREFIX wdt: <http://www.wikidata./prop/direct/>
SELECT ?x ?xLabel ?xLang WHERE {
?x rdfs:label "Popocatépetl"@en .
?x rdfs:label ?xLabel .
FILTER NOT EXISTS {
BIND ( lang(?xLabel) as ?xLang )
VALUES ( ?xLang ?p ) { ('en' 1) ('mul' 2) ('de' 3) ('fr' 4) }
?x rdfs:label ?xLabel1 .
BIND ( lang(?xLabel1) as ?xLang1 )
VALUES ( ?xLang1 ?p1 ) { ('en' 1) ('mul' 2) ('de' 3) ('fr' 4) }
FILTER ( ?p1 < ?p )
}
}
There are two problems with this, it doesn't work in MilleniumDB, due to a bug, and runs out of memory in QLever, due to how EXISTS
is implemented.
It does have the benefit of only having two "lookups" for any number of languages.
It doesn't even work in Blazegraph, maybe because the query isn't actually correct. What does work is
PREFIX rdfs: <http://www.w3./2000/01/rdf-schema#>
PREFIX wd: <http://www.wikidata./entity/>
PREFIX wdt: <http://www.wikidata./prop/direct/>
SELECT ?x ?xLabel ?xLang WHERE {
?x rdfs:label "Popocatépetl"@en .
?x rdfs:label ?xLabel .
BIND ( lang(?xLabel) as ?xLang )
VALUES ( ?xLang ?p ) { ('en' 1) ('mul' 2) ('de' 3) ('fr' 4) }
FILTER NOT EXISTS {
BIND ( lang(?xLabel) as ?xLang )
VALUES ( ?xLang ?p ) { ('en' 1) ('mul' 2) ('de' 3) ('fr' 4) }
?x rdfs:label ?xLabel1 .
BIND ( lang(?xLabel1) as ?xLang1 )
VALUES ( ?xLang1 ?p1 ) { ('en' 1) ('mul' 2) ('de' 3) ('fr' 4) }
FILTER ( ?p1 < ?p )
}
}
Here are some timing results in milliseconds for four SPARQL engines on four different label queries. The first two queries just use an OPTIONAL to get the German or English label. The third uses the COALESCE method above. The last, in Blazegraph only, uses the Wikibase label service. Each query is run three times, for the labels of all direct instances of volcano, then mountain, and then human. The queries for each engine were run from a cold start, so the German-only queries act like a warmup to level out the playing field for the other queries. All the runs are on a local machine with a Ryzen 9950X, 192GB of memory, and fast SSDs.
What can be seen is that QLever is the fastest engine for getting labels and that the full COALESCE query is only slightly slower than a single-language query for QLever. Moving from the Wikibase label service in Blazegraph to a COALESCE query in QLever will result in dramatic speedups.
1 Blazegraph 770 Count= 2070 200 German-only for volcano
2 Blazegraph 11037 Count= 518481 200 German-only for mountain
3 Blazegraph 47706 Count= 666225 200 ERROR MEMORY EXCEPTION German-only for human
4 Blazegraph 444 Count= 2070 200 English-only for volcano
5 Blazegraph 5276 Count= 518481 200 English-only for mountain
6 Blazegraph 38946 Count= 708808 200 ERROR MEMORY EXCEPTION English-only for human
7 Blazegraph 295 Count= 2070 200 Coalesce for volcano
8 Blazegraph 14518 Count= 518481 200 Coalesce for mountain
9 Blazegraph 43557 None 500 ERROR MemoryManagerOutOfMemory Coalesce for human
10 Blazegraph 387 Count= 2070 200 Wikibase label service for volcano
11 Blazegraph 12548 Count= 518481 200 Wikibase label service for mountain
12 Blazegraph 600123 Count= 8565341 200 ERROR TIMEOUT DURING RESULT GENERATION Wikibase label service for human
1 QLever 212 Count= 2070 200 German-only for volcano
2 QLever 3312 Count= 518481 200 German-only for mountain
3 QLever 39306 Count= 11463628 200 German-only for human
4 QLever 289 Count= 2070 200 English-only for volcano
5 QLever 658 Count= 518481 200 English-only for mountain
6 QLever 12339 Count= 11463628 200 English-only for human
7 QLever 60 Count= 2070 200 Coalesce for volcano
8 QLever 722 Count= 518481 200 Coalesce for mountain
9 QLever 13299 Count= 11463628 200 Coalesce for human
1 MilleniumDB 338 Count= 2070 200 German-only for volcano
2 MilleniumDB 20536 Count= 518481 200 German-only for mountain
3 MilleniumDB 198100 Count= 11463628 200 German-only for human
4 MilleniumDB 9 Count= 2070 200 English-only for volcano
5 MilleniumDB 993 Count= 518481 200 English-only for mountain
6 MilleniumDB 34935 Count= 11463628 200 English-only for human
7 MilleniumDB 14 Count= 2070 200 Coalesce for volcano
8 MilleniumDB 1621 Count= 518481 200 Coalesce for mountain
9 MilleniumDB 73291 Count= 11463628 200 Coalesce for human
1 Virtuoso 12836 Count= 2070 200 German-only for volcano
2 Virtuoso 66669 Count= 518481 200 German-only for mountain
3 Virtuoso 34828 Count= 1048576 200 German-only for human
4 Virtuoso 63 Count= 2070 200 English-only for volcano
5 Virtuoso 3861 Count= 518481 200 English-only for mountain
6 Virtuoso 18687 Count= 1048576 200 English-only for human
7 Virtuoso 123 Count= 2070 200 Coalesce for volcano
8 Virtuoso 6760 Count= 518481 200 Coalesce for mountain
9 Virtuoso 38811 Count= 1048576 200 Coalesce for human
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744745241a4591254.html
评论列表(0条)