首页 > 解决方案 > SPARQL 地理空间查询 (MarkLogic)

问题描述

在这里继续上一个问题。注意到fn:doc()在 SPARQL 查询中应避免避免。但是,对于除了下面显示的代码之外的地理空间查询,我无法找到替代解决方案。我也使用过这个查询,它的运行时间真的很慢。对于更大的数据集,它将达到 1 小时超时。

因此,我想问一下是否有更好的方法来实现 SPARQL 的地理空间查询?是否可以将 GEOSPARQL 与 一起使用PREFIX spatial:<http://jena.apache.org/spatial#>

xquery version "1.0-ml";
import module namespace sem = "http://marklogic.com/semantics" at "/MarkLogic/semantics.xqy";
import module namespace thsr="http://marklogic.com/xdmp/thesaurus" 
                             at "/MarkLogic/thesaurus.xqy";

let $query := sem:sparql(
'
PREFIX xs: <http://www.w3.org/2001/XMLSchema#>
PREFIX cts: <http://marklogic.com/cts#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema/>
PREFIX fn: <http://www.w3.org/2005/xpath-functions#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX db: <http://dbpedia.org/resource/>
PREFIX onto: <http://dbpedia.org/ontology/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns>
PREFIX xdmp: <http://marklogic.com/xdmp#>

SELECT *
WHERE{
?people </posted> ?question .
FILTER (cts:contains(fn:doc(?people), 
cts:path-geospatial-query("/people_data/location",  cts:circle(10, cts:point(59,28)))
)) .
}',
(),
(),
()
)

return (xdmp:elapsed-time())

=======更新========

问题带到线程

标签: sparqlmarklogic

解决方案


我在这里看到两个选项:

  • 要么您使用 MarkLogic 中内置的地理空间功能直接从 SPARQL 内部查找地理空间重叠,最好比较 RDF 属性,而不是路径索引中的值(仍然不是最佳的)
  • 更好:预取与您的地理空间约束匹配的文档列表,并将其作为约束馈送到您的 SPARQL(这应该是高性能的)

类似于以下内容:

let $uris := cts:uris((), (), cts:path-geospatial-query("/people_data/location",  cts:circle(10, cts:point(59,28))))
return sem:sparql('
  SELECT *
  WHERE{
    ?person </posted> ?question .
    FILTER (?person = ?people) .
  }
', map:entry("people", $uris))

对上述示例稍微更方便、更好优化的方法是使用 Optic API 重写它。它专门设计用于提供一种高性能的方式来弥合各种数据模型之间的差距。

推断上面的代码,我认为它会在光学代码中读到这样的内容:

import module namespace op="http://marklogic.com/optic" at "/MarkLogic/optic.xqy";

let $people := op:from-lexicons(
  map:entry("people", cts:uri-reference()),
  "lexicon"
)
  => op:where(
    cts:path-geospatial-query("/people_data/location", cts:circle(10, cts:point(59,28)))
  )

let $questions := op:from-sparql('SELECT * WHERE { ?person </posted> ?question. }', "sparql")

return $people
  => op:join-inner(
    $questions,
    op:on(
      op:view-col("lexicon", "people"),
      op:view-col("sparql", "person")
    )
  )
  =>op:result()

如果没有适当的数据和索引,测试它有点困难,但我希望它足以让你开始。

您可以在此处找到有关它的介绍性文档:

https://docs.marklogic.com/guide/app-dev/OpticAPI

API 参考可以在这里找到:

https://docs.marklogic.com/op


推荐阅读