【问题标题】:SPARQL Geospatial Queries (MarkLogic)SPARQL 地理空间查询 (MarkLogic)
【发布时间】:2019-05-28 09:41:28
【问题描述】:

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

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

问题转至thread

【问题讨论】:

  • 我认为 MarkLogic 不支持 GeoSPARQL,至少他们的文档中没有提到。
  • @AKSW 我看看是不是这种情况在尝试同时使用地理空间 + Sparql 时有什么推荐的方法吗?

标签: sparql marklogic


【解决方案1】:

我在这里看到两个选项:

  • 您可以使用 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

HTH!

【讨论】:

  • 嗨,我已经阅读了关于 optic api 的 abit ,它似乎可以在带有前缀的 xquery 中使用。您可以向我展示一个用于地理空间查询的示例光学 api 吗?谢谢@grtjn
  • 我用受过良好教育的尝试更新了答案,但还没有一路测试。
  • 我已经实现了如图所示的查询,一切正常,但由于某种原因,op:join-inner 返回一个空序列,另一方面,我尝试使用op:join-left-outer,它返回了@987654327 的所有值@ 对于所有条目都为 null。我检查过lexicon.peoplesparql.person 的值肯定相同。我已经更新了来自lexiconsparql 的示例数据
  • 嗯,值需要完全匹配。 /people/Aaren_DETERS/00001/people/Aaren_Howk/00001 不会匹配,尽管它们看起来很相似..
  • 是的,这只是一个样本数据,其中有一些值完全匹配。例如,lexicon.people 第 3 行的值与 sparql.person 第 27 行的值完全匹配。对不起,我编辑它以更改 ID 索引。 @grtjn
猜你喜欢
  • 2019-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-07
  • 2013-09-25
  • 2018-04-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多