Сравнение меток в федеративном запросе

У меня работает экземпляр 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 не встречается в удаленных тройных паттернах - но "думает", что они были пройдены.

Эта ошибка вызывает обе ваши проблемы:

  1. Попробуйте приведенный выше запрос на Wikidata (0 результатов)
  2. Попробуйте приведенный выше запрос на 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)),

Смотрите также

Другие вопросы по тегам