2016-09-09 1 views
3

J'ai un cas d'utilisation dans lequel je souhaite envoyer une notification chaque fois que des triplets sont ajoutés ou supprimés dans MarkLogic. La notification devrait contenir ces triplets et devrait indiquer s'ils ont été ajoutés ou supprimés.Utilisation des déclencheurs Marklogic 8 pour les triplets gérés

Je n'ai trouvé aucune mention dans le MarkLogic triggers guide concernant la façon dont cela pourrait fonctionner avec des triplets (gérés). Existe-t-il un moyen d'écrire un module de trigger de sorte que pour un document modifié (contenant les triplets gérés), comparez la nouvelle version avec l'ancienne version pour déterminer ce qui est ajouté et supprimé et envoyer une requête HTTP contenant ces changements?

Je comprends que doc ($ trgr: uri) me donnera l'état le plus récent du document en question - mais existe-t-il un moyen de récupérer la version précédente, avant le changement? Je suis assez nouveau pour MarkLogic et Xquery, donc des conseils sont très appréciés. Merci!

Répondre

2

Un grand merci à @grtjn pour avoir fourni le moyen d'accéder au document pré-changement. Pour déterminer la différence entre les documents, j'ai trouvé un moyen inspiré par ce blog post. La solution que j'ai trouvé à travailler ressemble à ceci:

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) 

J'ai créé 3 pre-commit déclencheurs, un pour chacun des trgr:document-content: les options create, modify et delete, tout en invoquant le module ci-dessus. Une requête de mise à jour SPARQL entraîne le déclenchement du module ci-dessus une ou plusieurs fois, l'impression des listes de triplets ajoutés et supprimés.

Couple d'observations:

  • Une seule instruction de mise à jour SPARQL peut créer, modifier et supprimer plusieurs documents, donc déclenchera plusieurs fois le module.
  • Les instructions INSERT semblent toujours créer de nouveaux documents, de sorte que vous n'obtiendrez jamais de triplets et de triplets supprimés dans le même appel.
  • Le code suppose qu'il existe une seule collection pour un document, qui est le graphique nommé pour les triplets gérés. Cela nécessitera un travail supplémentaire s'il doit y avoir plusieurs collections par document.
2

Je pense que vous ne pouvez y parvenir d'une manière:

  • utilisation pre-commit déclenche
  • utilisation xdmp:eval avec isolation pour different-transaction pour obtenir le document original

Quelque chose comme:

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)) 

J'ai effectué un test rapide avec un déclencheur pour la collection 'test'. J'ai ensuite inséré un document dans /test.xml avec le contenu <test>a</test>, et je ne l'ai pas encore ajouté au test de collecte. J'ai ensuite mis à jour le document avec <test>b</test>, et l'ai également ajouté au test de collecte pour activer le déclencheur. Il a enregistré a et b ..

Ceci montre comment vous pouvez obtenir le document original et mis à jour. Déterminer la différence est un défi en soi.

HTH!

+0

Merci! C'est exactement ce dont j'avais besoin pour commencer. – hhp