Many thanks to @grtjn for providing the way to access the pre-change document. For determining the difference between documents I found a way inspired by this blog post. The solution that I found to be working looks like this:
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)
I created 3 pre-commit
triggers, one for each of the trgr:document-content
options: create
, modify
and delete
, all invoking the above module. A SPARQL Update query will cause the above module to trigger one or more times, printing the lists of triples which were added and deleted.
Couple of observations:
- A single SPARQL Update statement can create, modify and delete multiple documents, so will trigger the module multiple times.
- INSERT statements seem to always create new documents, so you'll will never get added triples and deleted triples in the same invocation.
- The code assumes there's only one collection for a document, which is the named graph for managed triples. It will need extra work if there are to be multiple collections per document.