Сравнение меток в федеративном запросе
У меня работает экземпляр Wikibase. Я могу успешно выполнять федеративные запросы с помощью Wikidata. У меня есть определенные запросы, которые сравнивают метки, как это:
PREFIX xwdt: <http://www.wikidata.org/prop/direct/>
PREFIX xwd: <http://www.wikidata.org/entity/>
PREFIX xpq: <http://www.wikidata.org/prop/qualifier/>
PREFIX xps: <http://www.wikidata.org/prop/statement/>
PREFIX xp: <http://www.wikidata.org/prop/>
select ?item ?wditem ?itemLabel ?wid ?wditemlabel
where {
?item wdt:P17 wd:Q39.
?item wdt:P31 wd:Q5.
optional {
?item wdt:P14 ?wid .
}
?item rdfs:label ?itemLabel.
SERVICE <https://query.wikidata.org/sparql> {
?wditem xwdt:P27 xwd:Q258.
?wditem xwdt:P106 xwd:Q937857.
?wditem rdfs:label ?wditemlabel.
filter(LANGMATCHES(LANG(?wditemlabel), "en")).
}
filter(contains(?wditemlabel, ?itemLabel))
}
group by ?item ?itemLabel ?wid ?wditem ?wditemlabel
Вышеуказанное работает и соответствует элементам по их ярлыкам:
1) у меня изначально было filter(contains(?wditemlabel, ?itemLabel))
внутри предложения SERVICE, и он не дал результатов. Но, похоже, это сработало, если бы я использовал статическую строку для одной из переменных (например, filter(contains("test string", ?itemLabel))
). Почему это работает при сравнении переменной и строки, но не двух переменных?
2) Я ожидал, что запрос будет работать без "group by" в конце. Но, похоже, без этого происходит какое-то перекрестное соединение / декартово произведение, и каждый сопоставляемый элемент повторяется общее количество раз (n * n). Какая часть запроса вызывает это?
1 ответ
Выполняя федеративный запрос, ваш локальный Blazegraph выполняет такие запросы в Wikidata:
SELECT ?wditem ?wditemlabel
WHERE {
?wditem wdt:P27 wd:Q258.
?wditem wdt:P106 wd:Q937857.
?wditem rdfs:label ?wditemlabel.
filter(LANGMATCHES(LANG(?wditemlabel), "en"))
filter(contains(?wditemlabel, ?itemlabel))
}
VALUES () {
( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( )
( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( )
( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( )
( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( )
( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( )
} # 100 values
Как видите, Blazegraph "забывает" передавать локальные привязки ?itemLabel
в VALUES
- вероятно, потому что ?itemLabel
не встречается в удаленных тройных паттернах - но "думает", что они были пройдены.
Эта ошибка вызывает обе ваши проблемы:
- Попробуйте приведенный выше запрос на Wikidata (0 результатов)
- Попробуйте приведенный выше запрос на Wikidata без
contains
(Результат 82800 вместо 828)
обходные
Принудительный порядок выполнения запроса с использованием подсказок:
select ?item ?wditem ?itemLabel ?wditemlabel
where {
hint:Query hint:optimizer "None"
SERVICE <https://query.wikidata.org/sparql> {
?wditem wdt:P27 wd:Q258.
?wditem wdt:P106 wd:Q937857.
?wditem rdfs:label ?wditemlabel.
filter(lang(?wditemlabel)= "en").
}
?item wdt:P17 wd:Q39.
?item wdt:P31 wd:Q5.
?item rdfs:label ?itemLabel.
filter(contains(?wditemlabel, ?itemLabel))
}
или же
select ?item ?wditem ?itemLabel ?wditemlabel
where {
?item wdt:P17 wd:Q39.
?item wdt:P31 wd:Q5.
?item rdfs:label ?itemLabel.
SERVICE <https://query.wikidata.org/sparql> {
?wditem wdt:P27 wd:Q258.
?wditem wdt:P106 wd:Q937857.
?wditem rdfs:label ?wditemlabel.
filter(lang(?wditemlabel)= "en").
}
hint:Prior hint:runFirst true .
filter(contains(?wditemlabel, ?itemLabel))
}
Кстати, вы могли бы использовать DISTINCT
вместо GROUP BY
в исходном запросе или используйте дополнительную локальную фильтрацию, т.е. filter(lang(?itemLabel)='ast')
,
сравнение
В GraphDB оригинальный запрос работает хорошо, но его следует заменить contains(?wditemlabel, ?itemLabel)
с contains(str(?wditemlabel), str(?itemLabel))
,
Смотрите также
Федеративный запрос (Blazegraph wiki)
Ускорить федеративный запрос (вопрос по SO)