在MarkLogic中,我想编写创建文档/地图的函数,然后访问该查询中的那些文档/地图 - 我相信这样做可以避免内存问题/超时。
但是,除非我在单独的查询中运行每个函数,否则代码不起作用。如何强制一个函数只在另一个函数完成时运行:即将文档保存到磁盘?
修改 我遇到的问题是我想要找到两个元素的不同值,比如说和文档集合中的元素。我还想知道这些元素的每个值组合的出现频率。
我希望能够创建的结果看起来像是在一个文档集合中,每个文档都包含一个包含id的元素并包含一个代表一个人的字符串:
<pairs>
<pair frequency="5">
<thing-1>01257</thing-1>
<thing-2>John Smith</thing-2>
</pair>
</pairs>
这是我一直在使用的代码:
xquery version "1.0-ml";
declare namespace local = "http://www.local.com";
declare variable $collections := 'A' ;
declare variable $query-name := 'A-query' ;
declare variable $number-of-documents := count(collection($collections)) ;
declare variable $map-collection := concat ($query-name, '-maps') ;
(: create a temporary collection to store data saved during the query :)
declare function local:document-set-creator($counter, $iteration) {
if ($counter > ($number-of-documents + 1000))
then ()
else (
let $name := concat($query-name, '-part', $iteration)
let $uris := for $i in subsequence(cts:uris( (), (), cts:collection-query($collections) ), $counter, 1000) return $i
let $results :=
<results>
{
for $i in $uris
let $thing-1 := cts:search(/*/element/thing-1 , cts:document-query($i) )
let $thing-2 := cts:search(/*/element/thing-2 , cts:document-query($i) )
return
<pair>
<thing1>{$thing-1/normalize-space(string())}</thing1>
<thing2>{$thing-2/normalize-space(string())}</thing2>
</pair>
}
</results>
let $path-name := concat('pairs-', $name, '.xml')
return
xdmp:document-insert($path-name , $results, (), $query-name )
,
xdmp:sleep(1000)
,
local:document-set-creator(($counter + 1000), ($iteration + 1))
)
} ;
(: take values from the pairs list, concatenate them and put them into a map
key = concatenated value
value = frequency
:)
declare function local:create-pair-maps() {
for $i in collection($query-name)
return
local:write-maps(base-uri($i))
} ;
declare function local:write-maps($uri) {
let $document := doc($uri)
let $output-document := concat(substring-before(string($uri), '.xml') , '-MAP.xml')
let $value-map := map:map()
let $fill-the-map := for $pair in $document//pair
let $thing-1 := $pair/courtname/string()
let $thing-2 := $pair/courtcode/string()
let $value := concat($thing-1, '_', $thing-2)
return
if ( $value = map:keys($value-map) )
then map:put($value-map , $value ,
(map:get($value-map , $value) + 1) )
else map:put($value-map , $value , 1)
let $map-container := <container>{$value-map}</container>
return
xdmp:document-insert($output-document , $map-container, (), $map-collection )
} ;
(: combine maps :)
declare function local:combine-maps() {
let $maps := for $i in collection($map-collection) return $i
let $output-document := concat($query-name, '-combined-map.xml')
let $value-map-2 := map:map()
let $fill-the-map := for $_m in $maps
let $m := map:map($_m/container/map:map)
for $key in map:keys($m)
return
if ($key = map:keys($value-map-2))
then map:put($value-map-2 , $key ,
(map:get($value-map-2 , $key) + map:get($m , $key)))
else map:put($value-map-2 , $key , map:get($m , $key))
let $map-container := <container>{$value-map-2}</container>
return
xdmp:document-insert($output-document , $map-container, (), $map-collection)
} ;
(: write results to spreadsheet-friendly XML structure :)
declare function local:maps-to-spreadsheet() {
let $input-document-name := concat($query-name , '-combined-map.xml')
return
<results>{
for $i in doc($input-document-name)/container/map:map/map:entry
let $thing-2 := substring-before($i/@key/string(), '_')
let $thing-1 := substring-after($i/@key/string(), '_')
order by $thing-2
return
<pair frequency="{$i/map:value/string()}">
<thing-1>{$thing-1}</thing-1>
<thing-2>{$thing-1}</thing-2>
</pair>
}
</results>
};
local:document-set-creator(1, 1) ,
local:create-pair-maps() ,
local:combine-maps() ,
local:maps-to-spreadsheet()
答案 0 :(得分:0)
请考虑将https://docs.marklogic.com/cts:values或https://docs.marklogic.com/cts:value-co-occurrences与范围索引一起使用,而不是构建自己的频率计数文档。尝试使用这些功能之一的map
选项。这比自己构建类似的功能要快得多,也更可靠。
那就是说,您可能对多语句交易感兴趣:https://docs.marklogic.com/guide/app-dev/transactions - 我写了一篇可能有用的教程:http://blakeley.com/blogofile/2013/06/21/introduction-to-multi-statement-transactions
但是,使用MST可能无法解决内存消耗或超时的原始问题。通过插入这些临时文档,您可能最终会使用更多内存和更多时间,而不是仅仅在功能之间传递map:map
项目。