首页 > 解决方案 > Sparql 防止循环查询 (MarkLogic)

问题描述

嗨,我目前正在尝试在 Marklogic 中使用 SPARQL 进行一些分析,并且想知道是否可以防止循环查询?为了解释知道这一点的原因,我们将使用以下数据模型

在此处输入图像描述

假设我从 A 开始,最重要的是我想找到 A 和 G 之间的所有节点。在 sparql 中运行以下查询

node_A </link>* x
y </link>* node_G
x </link> y

我将无法获取它们之间的每个节点,因为例如我将丢失节点 B。由于我相信 MarkLogic Sparql 不是最新的(版本 1.1),我将无法使用“或”运算符来解决这个问题。因此,下一个解决方案是确保每个节点相互指向和相互连接,从而形成连接,例如

B=>F
F=>B

但是这样做会导致节点循环,因此,我很好奇是否可以防止 SPARQL 查询中的循环。或者,如果有任何其他方法可以检索节点 X 和节点 Y 之间的所有节点,请告诉我。

===更新===

使用的查询

xquery version "1.0-ml";

import module namespace sem = "http://marklogic.com/semantics" at "/MarkLogic/semantics.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 DISTINCT ?x ?y
WHERE{
?x !</path> ?y .
}
',
(),
(),
()
)

return (
$query,
xdmp:elapsed-time(),
"Nil",
"Nil",
"Nil"
)

遇到错误

[1.0-ml] XDMP-UNEXPECTED: (err:XPST0003) Unexpected token syntax error, unexpected !

标签: sparqlmarklogic

解决方案


我想你在寻找|and ^。第一个是“或”,后者允许反向跟随谓词。以下代码对我来说似乎运行良好。我正在运行 ML 10,但很确定它在 9 和 8 中也同样有效:

xquery version "1.0-ml";

xdmp:document-insert('/test/triples.json', object-node {
  "triple": array-node {
    sem:triple(sem:iri("node_A"), sem:iri("/link"), sem:iri("node_C")),
    sem:triple(sem:iri("node_D"), sem:iri("/link"), sem:iri("node_C")),
    sem:triple(sem:iri("node_C"), sem:iri("/link"), sem:iri("node_B")),
    sem:triple(sem:iri("node_C"), sem:iri("/link"), sem:iri("node_E")),
    sem:triple(sem:iri("node_F"), sem:iri("/link"), sem:iri("node_B")),
    sem:triple(sem:iri("node_F"), sem:iri("/link"), sem:iri("node_E")),
    sem:triple(sem:iri("node_F"), sem:iri("/link"), sem:iri("node_G")),
    sem:triple(sem:iri("node_E"), sem:iri("/link"), sem:iri("node_G"))
  }
})

;

sem:sparql("
SELECT DISTINCT ?x
WHERE {
  <node_A> (</link>|^</link>)* ?x.
  ?x (</link>|^</link>)* <node_G>.
  FILTER( !(?x = (<node_A>, <node_G>)) )
}
ORDER BY ?x
")


推荐阅读