当前位置: 首页 > 知识库问答 >
问题:

用SPARQL查询开放数据社区数据

萧奇
2023-03-14

我试图从下层超级输出区域(LSOAs)和英国邮政编码数据集中获取一些信息。

共有1个答案

弓晔
2023-03-14

检索所需数据有两个主要选项。在某些情况下,可以使用公共可用的SPARQLendpoint查询数据。这可能是最方便的方法,除非有某种明确的原因需要本地数据,否则也是可以采用的方法。但是,这种方法有局限性,在这种情况下,下载数据集并在本地对其进行查询是有意义的。我将首先描述远程endpoint解决方案,然后描述使用本地查询的解决方案。SPARQLendpoint上的限制(例如,硬超时)意味着第一种方法对于这个特定任务是不够的,所以这个问题的具体答案是第二种方法。

在提出这个问题之前,我并不熟悉这些特定的数据集和本体,因此第一种方法也经历了“熟悉数据”的过程。

有一个Open Data Communities SPARQLendpoint,您可以在该endpoint上运行查询并获取一些数据。我以前没有看过这些数据,所以不只是公布最终的答案,我将遍历我用来计算运行哪种查询的过程。

http://data.ordnancesurvey.co.uk/ontology/postcode/PostcodeUnit
SELECT * WHERE { 
  ?postcodeUnit a <http://data.ordnancesurvey.co.uk/ontology/postcode/PostcodeUnit>
}
LIMIT 10

在上面链接的endpoint中。(limit有助于确保结果及时返回,并且我们不会要求服务器做太多的事情。)这会产生如下结果

--------------------------------------------------------------
| postcodeUnit                                               |
==============================================================
| <http://data.ordnancesurvey.co.uk/id/postcodeunit/TA219HB> |
| <http://data.ordnancesurvey.co.uk/id/postcodeunit/TF109DS> |
| <http://data.ordnancesurvey.co.uk/id/postcodeunit/SY256SA> |
| <http://data.ordnancesurvey.co.uk/id/postcodeunit/SY147HR> |
| <http://data.ordnancesurvey.co.uk/id/postcodeunit/TF107BZ> |
| <http://data.ordnancesurvey.co.uk/id/postcodeunit/SY134LH> |
| <http://data.ordnancesurvey.co.uk/id/postcodeunit/TA202HF> |
| <http://data.ordnancesurvey.co.uk/id/postcodeunit/SY44QZ>  |
| <http://data.ordnancesurvey.co.uk/id/postcodeunit/TA116SS> |
| <http://data.ordnancesurvey.co.uk/id/postcodeunit/SY209DR> |
--------------------------------------------------------------

B72 1NB页显示其lsoa为Birmingham 006C。LSOA属性的IRI是(您可以在下载的数据中看到)

http://opendatacommunities.org/def/geography#lsoa

因此我们将SPARQL查询扩展为

SELECT * WHERE { 
  ?postcodeUnit
    a <http://data.ordnancesurvey.co.uk/ontology/postcode/PostcodeUnit> ;
    <http://opendatacommunities.org/def/geography#lsoa> ?lsoa .
}
LIMIT 10
-----------------------------------------------------------------------------------------------------------------------------
| postcodeUnit                                               | lsoa                                                         |
=============================================================================================================================
| <http://data.ordnancesurvey.co.uk/id/postcodeunit/TA219HB> | <http://opendatacommunities.org/id/geography/lsoa/E01029309> |
| <http://data.ordnancesurvey.co.uk/id/postcodeunit/TF109DS> | <http://opendatacommunities.org/id/geography/lsoa/E01029706> |
| <http://data.ordnancesurvey.co.uk/id/postcodeunit/SY147HR> | <http://opendatacommunities.org/id/geography/lsoa/E01018373> |
| <http://data.ordnancesurvey.co.uk/id/postcodeunit/TF107BZ> | <http://opendatacommunities.org/id/geography/lsoa/E01014172> |
| <http://data.ordnancesurvey.co.uk/id/postcodeunit/SY134LH> | <http://opendatacommunities.org/id/geography/lsoa/E01018514> |
| <http://data.ordnancesurvey.co.uk/id/postcodeunit/TA202HF> | <http://opendatacommunities.org/id/geography/lsoa/E01029175> |
| <http://data.ordnancesurvey.co.uk/id/postcodeunit/SY44QZ>  | <http://opendatacommunities.org/id/geography/lsoa/E01014204> |
| <http://data.ordnancesurvey.co.uk/id/postcodeunit/TA116SS> | <http://opendatacommunities.org/id/geography/lsoa/E01029225> |
| <http://data.ordnancesurvey.co.uk/id/postcodeunit/SW65TP>  | <http://opendatacommunities.org/id/geography/lsoa/E01001950> |
| <http://data.ordnancesurvey.co.uk/id/postcodeunit/TF15AX>  | <http://opendatacommunities.org/id/geography/lsoa/E01014155> |
-----------------------------------------------------------------------------------------------------------------------------
PREFIX pc: <http://data.ordnancesurvey.co.uk/ontology/postcode/>
PREFIX geo: <http://opendatacommunities.org/def/geography#>
SELECT * WHERE { 
  ?postcodeUnit
    a pc:PostcodeUnit ;
    geo:lsoa ?lsoa .
}
LIMIT 10

注释中的讨论指出,postcodeunits的数量会使结果集非常大。英国邮政编码数据集包含四种类型的资源,按大小顺序排列:邮政编码单位、邮政编码扇区、邮政编码区和邮政编码区域。这些类型的资源分别有1686911、10833、2087和120个。正如我所理解的评论中的澄清,想法是将这些与低层超级输出区(LSOA)相关联,例如伯明翰006C。单个邮政编码单元与LSOA相关联,但更高级别的邮政编码区域不相关联。每个邮政编码单元都在其部门、地区和区域内。例如,TA21 9Hb在TA、TA21 9和TA21内。使用这些信息,我们可以询问邮政编码单位及其相应的区(或扇区,或地区),以及它们的LSOA,并且只报告区和LSOA,而忽略单位本身。例如:

PREFIX pc: <http://data.ordnancesurvey.co.uk/ontology/postcode/>
PREFIX geo: <http://opendatacommunities.org/def/geography#>
PREFIX sr: <http://data.ordnancesurvey.co.uk/ontology/spatialrelations/>
SELECT DISTINCT ?district ?lsoa 
WHERE { 
  ?postcodeunit a pc:PostcodeUnit ;
                geo:lsoa ?lsoa ;
                sr:within ?district .
  ?district a pc:PostcodeDistrict .
}
LIMIT 10 

SPARQL结果

现在,数据集中有34378个LSOA,因此仍有大量数据需要选择,尝试下拉所有不同的LOSA/District映射的文本结果仍会导致超时。事实上,由于每个LSOA都与某个区域相关联(我预计),因此输出中的结果可能与LSOA的数量一样多。

PREFIX pc: <http://data.ordnancesurvey.co.uk/ontology/postcode/>
PREFIX geo: <http://opendatacommunities.org/def/geography#>
PREFIX sr: <http://data.ordnancesurvey.co.uk/ontology/spatialrelations/>
SELECT ?region ?lsoa 
WHERE { 
  {
    SELECT ?region WHERE { 
      ?region a pc:PostcodeDistrict .
    }
  }

  {
    SELECT ?lsoa WHERE { 
      ?postcodeunit a pc:PostcodeUnit ;
                    geo:lsoa ?lsoa ;
                    sr:within ?region .
    }
    LIMIT 1 
  }
}

SPARQL结果

使用SPARQLendpoint有一些限制,比如上面遇到的超时。在这些情况下,下载数据并将其放入Jena TDB存储并使用tdbquery进行查询并不困难。英国邮政编码页面有压缩的N-三元组的下载链接。下载完这些数据(并安装了Apache Jena 2.10)后,我(在Unix系统上)运行:

$ tdbloader2 --loc tdb dataset_data_postcodes_20130506183000.nt

其中tdb是一个本地目录,用于包含TDB的索引。加载数据需要一段时间(这里是1125秒),索引也是如此。加载完所有内容后,我将以下查询存储在名为postcodes.sparql的文件中,并使用

$ tdbquery --loc tdb --results CSV --query postcodes.sparql > unit_lsoa.csv
$ head -5 unit_lsoa.csv 
postcodeUnit,lsoa
http://data.ordnancesurvey.co.uk/id/postcodeunit/AL11AE,http://opendatacommunities.org/id/geography/lsoa/E01023667
http://data.ordnancesurvey.co.uk/id/postcodeunit/AL11AG,http://opendatacommunities.org/id/geography/lsoa/E01023741
http://data.ordnancesurvey.co.uk/id/postcodeunit/AL11AJ,http://opendatacommunities.org/id/geography/lsoa/E01023741
http://data.ordnancesurvey.co.uk/id/postcodeunit/AL11AR,http://opendatacommunities.org/id/geography/lsoa/E01023684
$ wc -l unit_lsoa.csv 
1440143 unit_lsoa.csv
PREFIX pc: <http://data.ordnancesurvey.co.uk/ontology/postcode/>
PREFIX geo: <http://opendatacommunities.org/def/geography#>
SELECT * WHERE { 
  ?postcodeUnit
    a pc:PostcodeUnit .
    FILTER NOT EXISTS { ?postcodeUnit geo:lsoa ?lsoa }
}
$ tdbquery --loc tdb \
    --results CSV \
    --query postcodes_without_lsoa.sparql > unit_without_lsoa.csv

果然,unit_without_lsoa.csv中大约有200,000行:

$ wc -l unit_without_lsoa.csv
246770 unit_without_lsoa.csv

1440143和246770的总和是1686913,这正好是邮政编码的数目(每个CSV文件中的头加上2行)。任务完成!

 类似资料:
  • 我不熟悉海龟格式的文件并用SPARQL查询它们。所以我有很多问题要解决,希望你能帮助我! 我有一个文件,名为设备CURT3.ttl并包含以下内容: 我正在使用Python3.5和一个名为RDFLib(https://github.com/RDFLib/rdflib)的库。我需要从一个文件称为设备读取CURT. rdf,将其序列化为设备3.ttl然后检索与设备相关的所有信息。例如,对于设备30883

  • 概述 使用find()方法在MongoDB集合中查询数据。MongoDB所有的查询范围都是单个集合的。也就是说MongoDB不能跨集合查询数据。 查询可以返回集合中的所有文档,或者仅仅返回指定过滤条件的文档。你可以指定一个过滤条件或才一个判断条件作为参数传递给find()方法。 find()方法在一个游标中返回所有的结果集,通过游标的迭代可以输出所有文档。 查询集合中的所有文档 查询集合中的所有文

  • 获取单个数据 获取单个数据的方法包括: 取出主键为1的数据 $user = UserModel::get(1); echo $user->user_nickname; // 使用数组查询 $user = UserModel::get(['user_nickname' => '老猫']); // 使用闭包查询 $user = UserModel::get(function($query){

  • 数据库操作使用 Db类封装方法,请事先在引入 Db类 use think\Db; 以上可以引入 Db,后面的文档不再说明,直接使用; 查询一个数据使用: // table方法必须指定完整的数据表名 Db::name('user')->where('id',1)->find(); find 方法查询结果不存在,返回 null 查询数据集使用: Db::name('user')->where('s

  • 获取单个数据 获取单个数据的方法包括: 取出主键为1的数据 $user = UserModel::find(1); echo $user->user_nickname; 如果你是在模型内部,请不要使用$this->user_nickname的方式来获取数据,请使用$this->getAttr('user_nickname') 替代。 或者在实例化模型后调用查询方法 $user = new Use

  • 数据库操作使用 Db类封装方法,请事先在引入 Db类 use think\facade\Db; 以上可以引入 Db,后面的文档不再说明,直接使用; 查询一个数据使用: // table方法必须指定完整的数据表名 Db::name('user')->where('id',1)->find(); find 方法查询结果不存在,返回 null 查询数据集使用: Db::name('user')->w