[英]MarkLogic: write data to documents in query and then access those documents in the same query
在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()
与其构建自己的频率计数文档,不如考虑将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 /多语句交易简介
但是,使用MST可能无法解决内存消耗或超时的原始问题。 与仅在函数之间传递map:map
项相比,通过插入这些临时文档,您可能最终会占用更多的内存和更多的时间。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.