ml-modules.root.com.marklogic.smart-mastering.algorithms.base.xqy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of marklogic-data-hub Show documentation
Show all versions of marklogic-data-hub Show documentation
Library for Creating an Operational Data Hub on MarkLogic
xquery version "1.0-ml";
(:~
: This module has functions for finding, setting up, and running match
: algorithms. The algorithm map is used to go from an algorithm specification
: in the match options to an actual function.
: Note that algorithms are allowed to have a setup function. See the
: algorithms:setup-algorithms function for more information.
:)
module namespace algorithms = "http://marklogic.com/smart-mastering/algorithms";
import module namespace algorithms = "http://marklogic.com/smart-mastering/algorithms"
at "double-metaphone.xqy",
"standard-reduction.xqy",
"zip.xqy",
"thesaurus.xqy";
import module namespace fun-ext = "http://marklogic.com/smart-mastering/function-extension"
at "../function-extension/base.xqy";
declare namespace matcher = "http://marklogic.com/smart-mastering/matcher";
(:~
: Wrapper for `fn:QName`, with the namespace assumed.
:)
declare function algorithms:default-function-lookup(
$name as xs:string,
$arity as xs:int)
{
fn:function-lookup(
fn:QName(
"http://marklogic.com/smart-mastering/algorithms",
$name
),
$arity
)
};
declare variable $_cached-algorithms-map as map:map := map:map();
(:~
: Build a map from an algorithm's name (see match options) to its
: xdmp:function.
: @param $algorithms-xml the algorithms element from the matcher options
: @return a map:map of the match algorithm functions
:)
declare function algorithms:build-algorithms-map($algorithms as node()*)
as map:map
{
let $key := xdmp:md5(xdmp:describe($algorithms, (), ()))
return
if (map:contains($_cached-algorithms-map, $key)) then
map:get($_cached-algorithms-map, $key)
else
let $algorithms-map as map:map :=
map:new((
for $algorithm as node() in $algorithms
let $name as xs:string? := $algorithm/(@name|name) ! fn:string(.)
let $function-name as xs:string := fn:string($algorithm/(@function|function|algorithmFunction))
let $module-namespace as xs:string := fn:string($algorithm/(@namespace|namespace|algorithmModuleNamespace))
let $module-path as xs:string := fn:string($algorithm/(@at|at|algorithmModulePath))
return
map:entry(
if (fn:exists($name)) then
$name
else
$module-path || ":" || $function-name,
fun-ext:function-lookup(
$function-name,
$module-namespace,
$module-path,
algorithms:default-function-lookup(?, 3)
)
)
))
return (
map:put($_cached-algorithms-map, $key, $algorithms-map),
$algorithms-map
)
};
(:~
: Each algorithm must provide a function that does the matching, but may also
: include a setup function. This function is run once, when the match options
: are loaded.
: @param $options the match options
: @return empty sequence
:)
declare function algorithms:setup-algorithms($options as element(matcher:options))
{
let $setup-map := algorithms:setup-map-from-xml($options/*:algorithms)
for $item in $options//*[@algorithm-ref]
return
fun-ext:execute-function(
map:get($setup-map, fn:string($item/@algorithm-ref)),
map:new((
map:entry("arg1", $item),
map:entry("arg2", $options)
))
)
};
(:~
: Deprecated. If we need to do automation for maintaining a dictionary, for example, we need to a better process.
:)
declare function algorithms:setup-map-from-xml($algorithms-xml as element(matcher:algorithms))
{
algorithms:setup-map-from-map(
algorithms:build-algorithms-map($algorithms-xml/*:algorithm)
)
};
(:~
:
:)
declare function algorithms:setup-map-from-map($algorithms-map)
{
map:new(
for $key in map:keys($algorithms-map)
let $funct := map:get($algorithms-map, $key)
return
let $annotation := fun-ext:get-function-annotation($funct, xs:QName("algorithms:setup"))
where fn:exists($annotation) and fn:not($annotation instance of null-node())
return
let $setup-function-details :=
if ($annotation instance of xs:string*) then
map:new(
for $item in $annotation
let $parts := fn:tokenize(fn:string($item), "=")
return
map:entry($parts[1], $parts[2])
)
else if ($annotation instance of object-node()) then
xdmp:from-json($annotation)
else
$annotation
let $module := (map:get($setup-function-details, "at"), xdmp:function-module($funct))[1]
let $setup-function :=
fun-ext:function-lookup(
fn:string(map:get($setup-function-details, "function")),
map:get($setup-function-details, "namespace"),
$module,
algorithms:default-function-lookup(?, 3)
)
where fn:exists($setup-function)
return
map:entry(
$key,
xdmp:apply(
$setup-function,
?,
?,
$setup-function-details
)
)
)
};
declare function algorithms:execute-algorithm($algorithm, $values, $ref-element, $options)
{
fun-ext:execute-function(
$algorithm,
map:new((
map:entry("arg1", $values),
map:entry("arg2", $ref-element),
map:entry("arg3", $options)
))
)
};
© 2015 - 2024 Weber Informatics LLC | Privacy Policy