1

我有一家三重商店,有 1.5 亿条语句,所有语句都包含几何图形。我目前正在使用 GraphDB 三重存储及其 geosparql 扩展。结合 geosparql 和过滤器查询时,端点只是在做一些奇怪的事情。GraphDB 方面已经确认他们的 geosparql 扩展存在一些问题。我只是想知道当 geosparql 查询与过滤器查询结合使用时,这是否正常。如果 geosparql 应该更快(例如在 virtuoso 中),我可能只是迁移到 virtuoso。否则,我可能需要提出其他解决方案。这可能会导致另一个更普遍的问题,在处理地理数据时,进行空间查询的有效方法是什么?

这是性能问题的示例。

这个查询(只是一个没有 geosparql 组件的过滤器查询)将需要 2-15 秒(这仍然是一个很长的时间):

PREFIX geo-pos: <http://www.w3.org/2003/01/geo/wgs84_pos#>
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
PREFIX geof: <http://www.opengis.net/def/function/geosparql/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX sf: <http://www.opengis.net/def/sf#>
select ?a
WHERE {
    ?a :hasPrimaryName ?o . 
    FILTER (contains(?o,'Paris'))
} 

这个查询(使用 GraphDB 中的 geosparql 扩展)大约需要 5 秒,有或没有限制:

PREFIX geof: <http://www.opengis.net/def/function/geosparql/>
PREFIX geo-pos: <http://www.w3.org/2003/01/geo/wgs84_pos#>
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
PREFIX omgeo: <http://www.ontotext.com/owlim/geo#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
select *
WHERE {
    ?a geo:hasGeometry ?aGeom .
    ?aGeom geo:asWKT ?aWKT .
    FILTER (geof:sfWithin(?aWKT, '''<http://www.opengis.net/def/crs/OGC/1.3/CRS84> POLYGON((1.549072265625 49.468124067331644,3.31787109375 49.468124067331644,3.31787109375 48.436489955944154,1.549072265625 48.436489955944154,1.549072265625 49.468124067331644))'''^^geo:wktLiteral))
}

无论我们是否使用限制,组合这两个查询都会超时(60 秒后):

PREFIX geo-pos: <http://www.w3.org/2003/01/geo/wgs84_pos#>
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
PREFIX geof: <http://www.opengis.net/def/function/geosparql/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX sf: <http://www.opengis.net/def/sf#>
select ?a
WHERE {
    ?a geo:hasGeometry ?aGeom .
    ?aGeom geo:asWKT ?aWKT .
FILTER (geof:sfWithin(?aWKT, '''<http://www.opengis.net/def/crs/OGC/1.3/CRS84> POLYGON((1.549072265625 49.468124067331644,3.31787109375 49.468124067331644,3.31787109375 48.436489955944154,1.549072265625 48.436489955944154,1.549072265625 49.468124067331644))'''^^geo:wktLiteral))
    ?a :hasPrimaryName ?o . FILTER (contains(?o,'Paris'))
}

由于我们通常使用三元存储作为 Web 地图界面的服务器,并且我们在 Web 地图中进行大量空间查询,因此 geosparql 查询的效率对我们很重要。查询时间如 60s 是我们不能接受的。有没有办法改善这种情况?使用服务器端(geosparql 查询)还是使用 web 地图端(我们使用 javascript)?谢谢!

4

1 回答 1

0

GraphDB 的 GeoSPARQL 支持对基于谓词的查询(例如?a geo:sfWithin ?b)使用索引,而基于函数的查询(例如filter(geof:sfWithin(?a, ?b)))需要完整扫描。您可以重写查询以利用谓词索引,例如

PREFIX geo-pos: <http://www.w3.org/2003/01/geo/wgs84_pos#>
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
PREFIX geof: <http://www.opengis.net/def/function/geosparql/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX sf: <http://www.opengis.net/def/sf#>
select ?a
WHERE {
    ?a geo:hasGeometry ?aGeom .
    ?aGeom geo:asWKT ?aWKT .
    ?aWKT geo:sfWithin '''<http://www.opengis.net/def/crs/OGC/1.3/CRS84> POLYGON((1.549072265625 49.468124067331644,3.31787109375 49.468124067331644,3.31787109375 48.436489955944154,1.549072265625 48.436489955944154,1.549072265625 49.468124067331644))'''^^geo:wktLiteral .
}

请注意,使用文字作为谓词的对象geo:sfWithin是 GraphDB 扩展,而不是标准的 GeoSPARQL 功能。

在您的完整查询中,您还使用contains(?o, 'Paris'). 这是一个缓慢的操作,因为它需要全面扫描。如果您需要全文搜索,您可以尝试使用 GraphDB Lucene 连接器之一,有关更多信息,请参阅http://graphdb.ontotext.com/documentation/free/lucene-graphdb-connector.html。GraphDB 的企业版还具有 Solr 和 Elasticsearch 的连接器。

于 2016-04-18T17:02:49.277 回答