在xsd:date上使用FILTER的意外行为

时间:2017-10-07 06:08:52

标签: xsd sparql virtuoso

如何过滤特定年份(1970年)的结果计数(发生罢工)?我的解决方案提供意外结果在查询中,我写下了我尝试的替代方案及其结果。

其他人提到的解决方案([1][2])没有解决问题。

端点是:   https://api.druid.datalegend.net/datasets/rlzijdeman/ClariahTech2017/containers/clariahTech2017/sparql

!d:: ; The trigger combination is [Alt]+d
MonitorOff:
    run, "C:\Program Files\MyPrograms\nircmd.exe" monitor off
return

1 个答案:

答案 0 :(得分:2)

关于"解决方案1":

函数yearxsd:dateTime类型的文字作为输入 - 您的数据仅包含xsd:datexsd:gYearMonth文字。这就是演员可能失败的原因。

关于"解决方案2":

也许是Virtuoso中的一个错误。但总的来说,我不确定你为什么需要这里的REGEX。如果您只想删除用于比较的语言标记,请使用str函数。它也快得多:

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX gg: <http://www.gemeentegeschiedenis.nl/gg-schema#>
PREFIX strikes: <https://iisg.amsterdam/vocab/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>

SELECT * {
  ?strike strikes:place ?splace .
  ?strike strikes:date ?sdate .
  ?muni rdf:type gg:Municipality .
  ?muni rdfs:label ?ggplace . 
  FILTER (?sdate >= '1970-01-01'^^xsd:date && ?sdate < '1971-01-01'^^xsd:date)
  FILTER(str(?splace) = str(?ggplace)) 
} 
LIMIT 10

在你的查询中我觉得奇怪的另一件事,你不应该计算罢工而不是市政当局吗?我的意思是,据我所知,你想得到特定日期每个市镇的罢工数量(如果我错了,请纠正我)。如果是这样,查询应如下所示:

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX gg: <http://www.gemeentegeschiedenis.nl/gg-schema#>
PREFIX strikes: <https://iisg.amsterdam/vocab/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>

SELECT ?muni (COUNT(?strike) as ?strikes) {
  ?strike strikes:place ?splace .
  ?strike strikes:date ?sdate .
  ?muni rdf:type gg:Municipality .
  ?muni rdfs:label ?ggplace . 
  FILTER (?sdate >= '1970-01-01'^^xsd:date && ?sdate < '1971-01-01'^^xsd:date)
  FILTER(str(?splace) = str(?ggplace)) 
} 
GROUP BY ?muni
LIMIT 10

此外,如果有多次罢工,获取?sdate并不合理,对吗?除非你想得到所有这些罢工的日期:

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX gg: <http://www.gemeentegeschiedenis.nl/gg-schema#>
PREFIX strikes: <https://iisg.amsterdam/vocab/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>

SELECT ?muni (COUNT(?strike) as ?strikes) (GROUP_CONCAT(?sdate; separator = ";") as ?s_dates) {
  ?strike strikes:place ?splace .
  ?strike strikes:date ?sdate .
  ?muni rdf:type gg:Municipality .
  ?muni rdfs:label ?ggplace . 
  FILTER (?sdate >= '1970-01-01'^^xsd:date && ?sdate < '1971-01-01'^^xsd:date)
  FILTER(str(?splace) = str(?ggplace)) 
} 
GROUP BY ?muni
LIMIT 10

次要评论

我还尝试先转换为xsd:dateTime,然后选择year

FILTER (year(xsd:dateTime(?sdate)) = 1970)
有趣的是,由于29.2,这失败了。 :D:

Virtuoso 22007 Error DT006: Cannot convert 1911-02-29 to datetime : Too many days (29, the month has only 28)

不确定,如果二月份的价值28在Virtuoso中被硬编码,或者它是否必然会闰年 - 至少这是有道理的,因为1911年不是闰年(1911年不能被整除4,因此,它是常见的一年)