2016-04-25 1 views
2

Это вопрос о Sparql и Wikidata. Я хочу сформулировать запрос, который возвращает отношение типа экземпляра, но если он недоступен, верните его подкласс. Я пробовал:Приоритет атрибута в запросе Sparql

SELECT DISTINCT ?ent_type WHERE { 

{ wd:Q7696957 wdt:P31 ?instanceof . } UNION 
{ wd:Q7696957 wdt:P31/wdt:P279? ?subclass . } UNION 
{ wd:Q7696957 wdt:P279* ?subclass . } 

BIND (IF (BOUND (?instanceof), ?instanceof, ?subclass) as ?ent_type ) 

Но к сожалению, это возвращает все решения, в то время как я только хочу одно решение

ent_type 
---------- 
wd:Q811979 
wd:Q386724 
wd:Q811430 
wd:Q7696957 
+0

Вы прогресс в этом? –

ответ

5

Вы можете использовать coalesce для достижения этой цели:

select distinct ?ent_type where { 
    optional { wd:Q7696957 wdt:P31 ?direct } 
    optional { wd:Q7696957 wdt:P31/wdt:P279? ?indirect } 
    optional { wd:Q7696957 wdt:P279* ?ancestor } 
    bind(coalesce(?direct, ?indirect, ?ancestor) as ?ent_type) 
} 
+0

ДОПОЛНИТЕЛЬНО быстрее? – Jay

+0

Союз и не обязательно, в общем, делают то же самое. Союз говорит, что «каждая строка будет иметь привязки, предоставляемые одним из этих шаблонов». Необязательно: «если привязки доступны для этого шаблона, а затем включить их в строку». Если есть возможные значения для? Direct,? Косвенных и? Ancestor, вы хотите, чтобы все они были в одной строке, так что вы можете выбирать между ними, а не в трех отдельных строках. Если вы хотите предпочитать значения для 'wdt: P31/wdt: P279?' Над 'wdt: P279 *', тогда вам нужен способ их отличить (например, используя разные переменные), чтобы вы могли выбирать между ними. –

+0

Итак, я использовал три разные переменные и ** optional **. Дело не в скорости. –

2

Чтобы упростить ответ Джошуа, вам действительно не нужна коалесценция:

select distinct ?ent_type where { 
    optional { wd:Q7696957 wdt:P31 ?ent_typee . } 
    optional { wd:Q7696957 wdt:P31/wdt:P279? ?ent_type . } 
    optional { wd:Q7696957 wdt:P279* ?ent_type . } 
} 

Если имеется несколько опций с одним и тем же именем переменной (здесь ?ent_type), первая «успешная» свяжет переменную.

Однако, существует проблема с вашей логикой запроса: если нет значения для wdt:P31, то для wdt:P31/wdt:P279? не существует, поэтому никогда не будет ситуации, когда выполняется среднее условие. Кроме того, wdt:P279* будет (из-за *) вернуть сам ресурс (wd:Q7696957), если нет значения для wdt:P279 (что может быть или не быть тем, что вы хотите).

+0

Согласен. Мой оригинальный запрос выглядит несколько иначе. Я должен включить весь запрос для описания проблемы. – Jay

+0

SELECT DISTINCT? Ent_type { {wd: Q7696957 wdt: P31? Instanceof. ? candid1 owl: equalClass? instanceof. } UNION {wd: Q7696957 wdt: P31/wdt: P279? подкласс1. ? кандидат2 сова: эквивалентClass? subclass1. } UNION {wd: Q7696957 wdt: P279 *? Subclass2. ? кандидат 3 сова: equalClass? subclass2. } BIND (coalesce (? Кандидат1,? Кандидат2,? Кандидат3) как? Ent_type)} Другими словами, найдите сопоставление своего экземпляра, для него нет доступных для него сопоставлений, попробуйте подкласс и, наконец, найдите сопоставления подкласс – Jay