Как пропустить неудачные даты в запросе SPARQL DBpedia?
Мне нужно получить данные о фильмах из DBpedia.
Я использую запрос SPARQL следующим образом: http://dbpedia-live.openlinksw.com/sparql:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?subject ?label ?released WHERE {
?subject rdf:type <http://dbpedia.org/ontology/Film>.
?subject rdfs:label ?label.
?subject <http://dbpedia.org/ontology/releaseDate> ?released.
FILTER(xsd:date(?released) >= "2000-01-01"^^xsd:date).
} ORDER BY ?released
LIMIT 20
Я попытался снять фильмы, выпущенные после 01.01.2000.
Но двигатель отвечает следующим образом:
Virtuoso 22007 Error DT006: Cannot convert 2009-06-31 to datetime :
Too many days (31, the month has only 30)
SPARQL query:
define sql:big-data-const 0
#output-format:text/html
define sql:signal-void-variables 1 define input:default-graph-uri <http://dbpedia.org> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?subject ?label ?released WHERE {
?subject rdf:type <http://dbpedia.org/ontology/Film>.
?subject rdfs:label ?label.
?subject <http://dbpedia.org/ontology/releaseDate> ?released.
FILTER(xsd:date(?released) >= "2000-01-01"^^xsd:date).
} ORDER BY ?released
LIMIT 20
Насколько я понимаю, в DBpedia есть некоторые ошибки в данных, и движок не может преобразовать строковые данные в тип даты, чтобы сравнить с установленной мной датой. И механизм прерывает выполнение запроса.
Итак, возникает вопрос: есть ли способ сообщить движку пропустить все ошибочные данные и вернуть мне все, что можно обработать?
Ответы
Ответ 1
Вы можете использовать COALESCE, чтобы определить дату по умолчанию для недопустимых:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?subject ?label ?released ?released_fixed WHERE {
?subject rdf:type <http://dbpedia.org/ontology/Film>.
?subject rdfs:label ?label.
?subject <http://dbpedia.org/ontology/releaseDate> ?released.
bind ( coalesce(xsd:datetime(?released), '1000-01-01') as ?released_fixed)
FILTER(xsd:date(coalesce(xsd:datetime(?released), '1000-01-01')) >= "2000-01-01"^^xsd:date).
} ORDER BY ?released
LIMIT 20
Этот запрос предоставляет следующие результаты SPARQL на конечной точке DbPedia Live
Конструкция связывания предназначена только для представления фиксированных дат, которые установлены в "1000-01-01" и сохраняются в переменной? release_fixed. Связывание не требуется для запроса и может быть опущено вместе с? Release_fixed в предложении SELECT
Ответ 2
Один из способов заключается в фильтрации с использованием типа данных, как вы можете видеть ниже:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?subject ?label ?released WHERE {
?subject rdf:type <http://dbpedia.org/ontology/Film>.
?subject rdfs:label ?label.
?subject <http://dbpedia.org/ontology/releaseDate> ?released.
FILTER(datatype(?released) = <http://www.w3.org/2001/XMLSchema#dateTime>)
FILTER(xsd:date(?released) >= "2000-01-01"^^xsd:date).
} ORDER BY ?released
LIMIT 20
Результаты SPARQL
Ответ 3
Отбрасывание результата с датой, которая отключена на один день, кажется мне глупым (например, Windows делает ошибку, когда что-то не так, например, ваш видеоадаптер GPU висит 5 раз подряд).
Поскольку вы заботитесь только об этом году, не лучше ли сравнивать по порядку?
str(?released) >= "2000"
XSD говорит "как минимум 4 цифры за год", поэтому это работает для всех положительных лет (AD).
Кстати, это также будет работать, если база извлечения DBpedia обнаружит только год в этом поле.