2014-02-08 1 views
3

У меня есть следующий запрос SPARQL:фильтр в SPARQL запроса

PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> 
PREFIX type: <http://dbpedia.org/class/yago/>  
PREFIX prop: <http://dbpedia.org/property/> 
SELECT * 
WHERE { 
    ?person a foaf:Person; 
    foaf:name ?name; 
    prop:deathCause ?death_cause. 
    FILTER (langMatches(lang(?name), "EN")) . 
} 
LIMIT 50 

Если запустить это здесь: http://dbpedia.org/snorql/

Вы увидите, что вы получите много результатов. Теперь я хотел бы отфильтровать одну причину смерти, скажем, «Трафик столкновения». Таким образом, это должно быть просто добавить фильтр:

FILTER (?death_cause = "Traffic collision"). 

Так запрос должен быть затем:

PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> 
PREFIX type: <http://dbpedia.org/class/yago/>  
PREFIX prop: <http://dbpedia.org/property/> 
SELECT * 
WHERE { 
    ?person a foaf:Person; 
    foaf:name ?name; 
    prop:deathCause ?death_cause. 
    FILTER (?death_cause = "Traffic collision"). 
    FILTER (langMatches(lang(?name), "EN")) . 
} 
LIMIT 50 

Однако это ничего не возвращает. Кто знает, что не так с запросом? Благодарю.

ответ

4

Вы увидите, что получите много результатов. Теперь я хотел бы отфильтровать одну причину смерти, скажем, «Трафик столкновения». Так что это должно быть просто путем добавления фильтра:

FILTER (?death_cause = "Traffic collision"). 

Фильтры определить, какие вещи вы держать, а не то, что вещи, которые вы удалите, так что если вы хотите, чтобы отфильтровать Out коллизий трафика, вы бы на самом деле хочет:

FILTER (?death_cause != "Traffic collision") 

Если вы попытаетесь это сделать, хотя, вы будете видеть столкновение трафика в результатах, потому что есть разница между "Traffic collision" и "Traffic collision"@en. Первый (который будет удалять ваш код) - это простой литерал (т. Е. Без типа данных или языкового тега). Последний является литералом с тегом языка "en". Это не то же самое, поэтому отфильтровать один не отфильтровывает другой, и сохранение одного не приведет к другому. Чтобы удалить "Traffic collision"@en, вы можете отфильтровать его с:

FILTER (?death_cause != "Traffic collision"@en) 

В качестве альтернативы, вы можете использовать функцию str получить лексическую часть буквального, так что вы можете отфильтровать "Traffic collision" независимо от тега языка (или типа данных , если он появился как машинописных буквального):

FILTER (str(?death_cause) != "Traffic collision") 

Таким образом:

PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> 
PREFIX type: <http://dbpedia.org/class/yago/>  
PREFIX prop: <http://dbpedia.org/property/> 
SELECT * 
WHERE { 
    ?person a foaf:Person; 
    foaf:name ?name; 
    prop:deathCause ?death_cause. 
    FILTER (langMatches(lang(?name), "EN")) . 
    FILTER (?death_cause != "Traffic collision"@en) 
} 
LIMIT 50 

SPARQL results

+1

Спасибо! Извините, я на самом деле не имел в виду _filter out_, мне нужна была одна причина смерти. Но удаление «!» в последнем запросе в вашем ответе решает, что и научиться фильтровать _out_, я считаю бонус! Небольшое продолжение: Какова причина добавления str() вокруг имени/переменной свойства? Это не очевидно. –

+1

@MariusLian Literals в RDF могут быть простыми (без языка или типа данных), набираться (с типом данных) или помечены тегом языка (с тегом языка). 'str' извлекает строку из всех трех видов. Я добавил больше объяснений в ответ. –

+0

Так что на самом деле в другом фильтре это то, что происходит. Функция lang() извлекает часть языка. Спасибо за четкое объяснение! –