Xquery 从MarkLogic7中的特定图形中选择三元组

Xquery 从MarkLogic7中的特定图形中选择三元组,xquery,marklogic,triplestore,triples,n-triples,Xquery,Marklogic,Triplestore,Triples,N Triples,我需要在MarkLogic中的不同图(集合)中提供类似三元组之间的隔离。为此,我必须指定要从哪个图形检索三元组,我的方法是: cts:triples( (), sem:iri("http://something/predicate#somepredicate"), "SomeObject", (), (), cts:collection-query("someCollection") ) 这是可行的,但由于集合查询的缘故,它的性能很差。有没有更好的方法将结果限制为给定图形的这些

我需要在MarkLogic中的不同图(集合)中提供类似三元组之间的隔离。为此,我必须指定要从哪个图形检索三元组,我的方法是:

cts:triples(
  (),
  sem:iri("http://something/predicate#somepredicate"), "SomeObject", (), (),
  cts:collection-query("someCollection") )  

这是可行的,但由于集合查询的缘故,它的性能很差。有没有更好的方法将结果限制为给定图形的这些结果?

如果集合查询是性能较差的部分,我会感到惊讶。不要被许多结果的回归所误导,这可能会让它看起来很慢。将事物放入计数或xdmp:estimate中以排除它

除了cts:triples之外,我只能想到带有from或GRAPH语句的sem:sparql


我试着用笔记本电脑上的7.0-4创建一个测试用例。对我来说,这似乎很快:看一看,看看它和你正在做的有什么不同。我猜您的查询会返回许多三元组,这就是瓶颈。匹配三元组非常快,但返回大量三元组可能相对较慢

首先,让我们使用taskbot生成一些三元组

(: insert test documents with taskbot :)
import module namespace tb="ns://blakeley.com/taskbot"
  at "src/taskbot.xqm" ;
import module namespace sem="http://marklogic.com/semantics" 
  at "MarkLogic/semantics.xqy";

tb:list-segment-process(
  (: Total size of the job. :)
  1 to 1000 * 1000,
  (: Size of each segment of work. :)
  500,
  (: Label. :)
  "test/triples",
  (: This anonymous function will be called for each segment. :)
  function($list as item()+, $opts as map:map?) {
    (: Any chainsaw should have a safety. Check it here. :)
    tb:maybe-fatal(),
    let $triples := $list ! sem:triple(
      sem:iri("subject"||xdmp:random()),
      sem:iri("predicate"||xdmp:random(19)),
      "object"||xdmp:random(49),
      sem:iri('graph'||xdmp:random(9)))
    return sem:rdf-insert($triples)
    ,
    (: This is an update, so be sure to commit each segment. :)
    xdmp:commit() },
  (: options - not used in this example. :)
  map:new(map:entry('testing', '123...')),
  (: This is an update, so be sure to say so. :)
  $tb:OPTIONS-UPDATE)
现在,taskbot在任务服务器上完成大部分工作。因此,监视ErrorLog.txt,或者等待CPU下降,三重计数达到1M。之后,让我们看看我们加载了什么:

count(cts:triples()),
count(cts:triples((), sem:iri("predicate0"))),
count(cts:triples((), (), "object0")),
count(
  cts:triples((), (), (), (), (), cts:collection-query("graph0")))
=>
1000000
49977
19809
100263
对于谓词、对象和集合,您可能会得到不同的计数:请记住,数据是随机生成的。但是,让我们尝试一个查询

count(
  cts:triples(
    (), sem:iri("predicate0"), "object0",
    (), (), cts:collection-query("graph0")))
, xdmp:elapsed-time()
结果:

100
PT0.004991S
这对我来说似乎很快:5毫秒。你可能会得到不同的计数,因为数据是随机生成的,但应该很接近

现在,一个更大的结果集将减缓这一速度。例如:

count(
  cts:triples(
    (), (), (),
    (), (), cts:collection-query("graph0")))
, xdmp:elapsed-time()
=>
100263
PT0.371252S

count(cts:triples())
, xdmp:elapsed-time()
=>
1000000
PT2.906235S

count(cts:triples()[1 to 1000])
, xdmp:elapsed-time()
=>
1000
PT0.002707S

如您所见,响应时间大约是O(n)和三元组的数量。事实上,它比O(n)好一点,但在这个范围内。在任何情况下,
cts:collection查询
看起来都不是问题。

MarkLogic的完整版本号是多少?什么是“性能差”的意思?让我们听听数字。数据库中有多少个三元组?有多少符合主题?有多少与该对象匹配?有多少和这个系列相匹配?示例查询需要多长时间?感谢您花时间进行如此彻底的测试!您是对的,事实证明它毕竟不是集合查询,而是返回的三元组的数量。