python - SPARQL 查询返回的行数比预期多

标签 python sparql rdflib

我正在尝试将以下 Turtle RDF 转换为 csv。我只想保留每个对象的 hasPlaceNamehasICAOcodehasWKT 的值:

:Place_Oberschleissheim_Airport a :Civil_Aerodrome
 ;  :hasPlaceName "OBERSCHLEISSHEIM"
 ;    :hasICAOcode "EDNX"
 ;  :elevationOfPlace "487.68"^^unit:meters
 ;  :hasGeometry :geom_11_55916690826416_48_239166259765625
 ;  :Aerodrome_serves_City :City_OBERSCHLEISSHEIM
 .  :City_OBERSCHLEISSHEIM a :City
 .  :geom_11_55916690826416_48_239166259765625 a :Geometry
 ;  :hasWKT "POINT (11.55916690826416 48.239166259765625)" .

:Place_Oberschleissheim_Airport a :Civil_Aerodrome
 ;  :hasPlaceName "OBERSCHLEISSHEIM"
 ;    :hasICAOcode "EDMX"
 ;  :elevationOfPlace "487.68"^^unit:meters
 ;  :hasGeometry :geom_11_565555572509766_48_23805618286133
 ;  :Aerodrome_serves_City :City_OBERSCHLEISSHEIM
 .  :City_OBERSCHLEISSHEIM a :City
 .  :geom_11_565555572509766_48_23805618286133 a :Geometry
 ;  :hasWKT "POINT (11.565555572509766 48.23805618286133)" .

这是我的 SPARQL 查询:

SELECT DISTINCT ?icao ?name ?wkt
WHERE {
    [] a :Civil_Aerodrome ;
        :hasPlaceName ?name ;
        :hasICAOcode ?icao ;
        :hasGeometry/:hasWKT ?wkt .
}

但是我得到了四条记录而不是两条:

(u'EDNX', 'u'OBERSCHLEISSHEIM', 'u'POINT (11.565555572509766 48.23805618286133)')
(u'EDMX', 'u'OBERSCHLEISSHEIM', 'u'POINT (11.565555572509766 48.23805618286133)')
(u'EDNX', 'u'OBERSCHLEISSHEIM', 'u'POINT (11.55916690826416 48.239166259765625)')
(u'EDMX', 'u'OBERSCHLEISSHEIM', 'u'POINT (11.55916690826416 48.239166259765625)')

我认为我遗漏了 SPARQL 语法中的某些内容。任何指向正确方向的线索将不胜感激。

最佳答案

您的 SPARQL 查询是正确的,结果也是正确的。问题出在您的数据中。

您已定义单个机场资源 :Place_Oberschleissheim_Airport。但是,您为这个单一机场提供了两个不同的国际民航组织代码和两组不同的坐标。

然后您提出一个查询,要求提供任何机场的国际民航组织、地名和坐标集的所有不同组合。只有一个机场,但有两个国际民航组织和两个坐标集,因此您的查询有四个唯一的结果:

icao code 1, coordinate 1
icao code 2, coordinate 1
icao code 1, coordinate 2
icao code 2, coordinate 2

解决方案是确保您的数据针对不同机场使用不同的标识符(或者更一般地说,确保每个机场的坐标和国际民航组织代码是唯一的)。

或者,如果数据确实必须保持这种方式,并且您希望查询返回每个机场的唯一结果,则您必须问自己应该返回哪个坐标和哪个国际民航组织代码。

如果答案是“只选择其中一个,我不在乎哪个”,您可以执行以下操作

SELECT DISTINCT (SAMPLE(?icao) as ?code) ?name (sample(?wkt) as ?coord)
WHERE {
    ?airport a :Civil_Aerodrome ;
        :hasPlaceName ?name ;
        :hasICAOcode ?icao ;
        :hasGeometry/:hasWKT ?wkt .
} group by ?airport ?name

结果:

Evaluating SPARQL query...
+------------------------+------------------------+------------------------+
| code                   | name                   | coord                  |
+------------------------+------------------------+------------------------+
| "EDNX"                 | "OBERSCHLEISSHEIM"     | "POINT (11.55916690826416 48.239166259765625)"|
+------------------------+------------------------+------------------------+
1 result(s) (13 ms)

另一方面,如果您想要两者都回来,您要么必须接受多几行,要么您可以将替代方案粘到一行中:

SELECT DISTINCT (GROUP_CONCAT(DISTINCT ?icao) as ?codes) ?name (GROUP_CONCAT(DISTINCT ?wkt) as ?coords)
WHERE {
    ?airport a :Civil_Aerodrome ;
        :hasPlaceName ?name ;
        :hasICAOcode ?icao ;
        :hasGeometry/:hasWKT ?wkt .
} group by ?airport ?name

结果:

Evaluating SPARQL query...
+------------------------+------------------------+------------------------+
| codes                  | name                   | coords                 |
+------------------------+------------------------+------------------------+
| "EDNX EDMX"            | "OBERSCHLEISSHEIM"     | "POINT (11.55916690826416 48.239166259765625) POINT (11.565555572509766 48.23805618286133)"|
+------------------------+------------------------+------------------------+
1 result(s) (2 ms)

关于python - SPARQL 查询返回的行数比预期多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52472457/

相关文章:

java - 在 Apache Jena 中聚合

rdf - 使用 SPARQL 查询 RDF 中的非 XSD、RDF 等数据类型

python - 使用 rdflib 获取数据库中的所有关系

python - 如何查找了解主题或其他方式的 rdf 对象?

Python单例模式

Python将字符串对象转换为字典

python - 如何使用 if 设置 true/false 变量?

sparql - 如何区分 SQL 三元组和显式三元组?

python - 在三元组中添加空白节点

python - 检查文件是否存在,如果不存在则创建它