我有一个用例,我想在每次从MarkLogic添加或删除三元组时发送通知。通知应包含这些三元组,并应说明它们是否已添加或删除。
我在MarkLogic triggers guide中没有发现任何关于它如何与(托管)三元组合作的提及。有没有办法编写触发器模块,以便对于修改后的文档(包含托管三元组),将新版本与旧版本进行比较,以确定添加和删除的内容,并发送包含这些更改的HTTP请求?
我理解doc($ trgr:uri)会给我这个文档的最新状态 - 但有没有办法在更改之前检索以前的版本?我是MarkLogic和Xquery的新手,因此非常感谢一些指导。谢谢!
答案 0 :(得分:2)
我认为你只能通过一种方式实现这一目标:
pre-commit
触发器xdmp:eval
isolation
different-transaction
获取原始文档类似的东西:
xquery version "1.0-ml";
import module namespace trgr = "http://marklogic.com/xdmp/triggers" at "/MarkLogic/triggers.xqy";
declare variable $trgr:uri as xs:string external;
xdmp:log("Triggered processing of " || $trgr:uri || ".."),
xdmp:log(xdmp:eval('doc("'||$trgr:uri||'")', (), <options xmlns="xdmp:eval"><isolation>different-transaction</isolation></options>)),
xdmp:log(doc($trgr:uri))
我运行了一个快速测试,其中一个触发器用于集合'test'。然后我在/test.xml中插入了一个内容为<test>a</test>
的doc,并没有将它添加到集合测试中。然后我用<test>b</test>
更新了文档,并将其添加到集合测试以激活触发器。它记录了a和b ..
这显示了如何获取原始文档和更新文档。确定差异本身就是一个挑战..
HTH!
答案 1 :(得分:2)
非常感谢@grtjn提供访问更改前文档的方法。为了确定文档之间的差异,我发现了一种受此blog post启发的方式。我发现工作的解决方案看起来像这样:
xquery version '1.0-ml';
import module namespace trgr='http://marklogic.com/xdmp/triggers' at '/MarkLogic/triggers.xqy';
declare function local:diff($seq1 as item()*, $seq2 as item()*) as item()* {
let $map1 := map:new($seq1 ! map:entry(fn:string(.), .))
let $map2 := map:new($seq2 ! map:entry(fn:string(.), .))
return map:keys($map1 - $map2) ! map:get($map1,.)
};
declare variable $trgr:uri as xs:string external;
declare variable $after := doc($trgr:uri)/sem:triples/sem:triple;
declare variable $before := xdmp:eval('doc("'||$trgr:uri||'")', (),
<options xmlns="xdmp:eval"><isolation>different-transaction</isolation></options>)/sem:triples/sem:triple;
declare variable $added_triples := local:diff($after, $before);
declare variable $added_graph := xdmp:document-get-collections($trgr:uri);
declare variable $deleted_triples := local:diff($before, $after);
declare variable $deleted_graph := xdmp:eval('xdmp:document-get-collections("'||$trgr:uri||'")', (),
<options xmlns="xdmp:eval"><isolation>different-transaction</isolation></options>);
xdmp:log(fn:concat('***** Trigger processing: ', $trgr:uri, '*****')),
xdmp:log('***** added triples *****'),
xdmp:log($added_graph),
xdmp:log($added_triples),
xdmp:log('***** deleted triples *****'),
xdmp:log($deleted_graph),
xdmp:log($deleted_triples)
我创建了3个pre-commit
个触发器,每个trgr:document-content
选项一个:create
,modify
和delete
,都调用了上述模块。 SPARQL Update查询将导致上述模块触发一次或多次,打印添加和删除的三元组列表。
观察结果: