【问题标题】:How to skip bad dates in DBpedia SPARQL request?如何跳过 DBpedia SPARQL 请求中的错误日期?
【发布时间】:2011-11-26 18:50:14
【问题描述】:

我需要从 DBpedia 获取有关电影的数据。

我在http://dbpedia-live.openlinksw.com/sparql上使用如下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

我试图获取 2000 年 1 月 1 日之后发行的电影。 但引擎回答如下:

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 中的数据存在一些错误,引擎无法将字符串数据转换为日期类型以与我设置的日期进行比较。引擎会中断查询执行。

那么,问题是:有什么方法可以告诉引擎跳过所有错误数据并将所有可以处理的数据返回给我?

【问题讨论】:

  • 看起来是 dbpedia 中的一个错误

标签: sparql dbpedia virtuoso


【解决方案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 Results on DbPedia Live Endpoint

绑定结构仅用于显示设置为“1000-01-01”并存储在变量?release_fixed中的固定日期。查询不需要绑定,可以在 SELECT 子句中与 ?release_fixed 一起省略

【讨论】:

  • 这里是否需要 bind() (如果需要,为什么)?我在有和没有 bind() 的情况下都试过了,仍然得到同样的错误 OP 报告。
  • 为了解释 bind(),我增强了我的答案。
【解决方案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 results

【讨论】:

  • 尝试运行该查询会导致错误:Virtuoso 22023 Error SR066: Unsupported case in CONVERT (incomplete RDF box -&gt; DATE)。这似乎与问题中的问题相似。
【解决方案3】:

在我看来,放弃一个日期差一天的结果似乎很愚蠢(就像 Windows 在感觉有问题时进行错误检查,例如你的 GPU 视频适配器连续挂起 5 次)。

既然你只关心年份,那么按字符串进行比较不是更好吗?

str(?released) >= "2000"

XSD 表示“一年至少有 4 位数字”,因此这适用于所有正数年份 (AD)。 顺便说一句,如果 DBpedia 提取框架在该领域仅发现一年,这也将起作用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-06
    • 1970-01-01
    • 1970-01-01
    • 2012-05-28
    相关资源
    最近更新 更多