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

У меня запущен экземпляр Викибазы. Я могу успешно выполнять федеративные запросы с Викиданными. У меня есть определенные запросы, которые сравнивают такие ярлыки:

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) Я ожидал, что запрос будет работать без "группировать по" в конце. Но похоже, что без него происходит какое-то перекрестное соединение/декартово произведение, и каждый совпадающий элемент повторяется общее количество раз (n * n). Какая часть запроса вызывает это?


person Elfalem    schedule 13.08.2018    source источник


Ответы (1)


Выполняя федеративный запрос, ваш локальный Blazegraph выполняет такие запросы к Викиданным:

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

or

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)).

См. также

person Stanislav Kralin    schedule 14.08.2018