2

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

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

这行得通,但由于收集查询,它的性能很差。有没有更好的方法将结果限制为仅给定图表的结果?

4

2 回答 2

3

我试图为此创建一个测试用例,在我的笔记本电脑上使用 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 在 Task Server 上完成大部分工作。所以监视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-query这看起来都不是问题。

于 2014-12-10T18:35:05.020 回答
0

如果集合查询是表现不佳的部分,我会感到惊讶。不要被仅仅返回许多结果所误导,这可能会使它看起来很慢。把东西放在一个计数或 xdmp:estimate 中以排除它。

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

于 2014-12-10T14:24:48.953 回答