2017-08-29 67 views
1

我必須複製MarkLogic服務器中的整個項目文件夾,而不是手動完成它,我決定用遞歸函數來完成它,但它正在成爲我所遇到過的最糟糕的想法。我遇到了交易和語法方面的問題,但是新的我沒有找到解決問題的真正方法。這是我的代碼,謝謝你的幫助!用XQuery遞歸複製一個文件夾

import module namespace dls = "http://marklogic.com/xdmp/dls" at "/MarkLogic/dls.xqy"; 

declare option xdmp:set-transaction-mode "update"; 

declare function local:recursive-copy($filesystem as xs:string, $uri as xs:string) 
{ 
    for $e in xdmp:filesystem-directory($filesystem)/dir:entry 
    return 
    if($e/dir:type/text() = "file") 
     then dls:document-insert-and-manage($e/dir:filename, fn:false(), $e/dir:pathname) 
    else 
     (
      xdmp:directory-create(concat(concat($uri, data($e/dir:filename)), "/")), 
      local:recursive-copy($e/dir:pathname, $uri) 
    ) 

}; 

let $filesystemfolder := 'C:\Users\WB523152\Downloads\expath-ml-console-0.4.0\src' 
let $uri := "/expath_console/" 

return local:recursive-copy($filesystemfolder, $uri) 
+0

多少文件都在複製,例如:這可以通過一個簡單的循環在xdmp實現呢?如果您的數據集非常大,那麼好的解決方案就會縮小。另外,你確定你需要dls嗎?你可能會好嗎?ol-xdmp:document-insert? –

+0

@SamMefford嗯,我試圖複製一個充當UI控制檯的整個嵌套項目來查看服務器本身內部的文件和文件夾的層次結構,因此不使用xdmp:document-insert將無濟於事。不,我不確定dls,我只是想找到一個解決方案。我也嘗試使用mlcp命令,但無法訪問服務器。 – MissArmstrong

回答

3

MLCP本來很好用。然而,這裏是我的版本:

declare option xdmp:set-transaction-mode "update"; 

declare variable $prefix-replace := ('C:/', '/expath_console/'); 

declare function local:recursive-copy($filesystem as xs:string){ 
    for $e in xdmp:filesystem-directory($filesystem)/dir:entry 
    return 
     if($e/dir:type/text() = "file") 
     then 
      let $source := $e/dir:pathname/text() 
      let $dest := fn:replace($source, $prefix-replace[1], $prefix-replace[2]) 
      let $_ := xdmp:document-insert($source, 
       <options xmlns="xdmp:document-load"> 
       <uri>{$dest}</uri> 
       </options>) 
      return <record> 
        <from>{$source}</from> 
        <to>{$dest}</to> 
        </record> 
     else 
      local:recursive-copy($e/dir:pathname) 

}; 

let $filesystemfolder := 'C:\Temp' 

return <results>{local:recursive-copy($filesystemfolder)}</results> 

請注意以下事項:

  • 我改變了我的樣品到C:\ TEMP目錄
  • 輸出是XML僅僅是因爲按照慣例我試着如果我想分析結果,請執行此操作。實際上,我發現與衝突更新相關的錯誤。
  • 我選擇定義一個簡單的前綴對URI的替代
  • 我看到了你的描述沒有必要DLS
  • 我認爲沒有必要明確創建的目錄在你的使用情況
  • 你的理由獲取衝突的更新,因爲您只使用文件名作爲URI。在整個目錄結構中,這些名稱不是唯一的 - 因此,對同一個URI的雙重插入進行衝突更新。
  • 這不是固體代碼:
    • 你將不得不確保一個URI是有效的。並非所有的文件系統路徑/名稱都可以用於URI,因此如果需要的話,您可能需要測試它並轉義字符。
    • 大文件系統會超時,因此批量產卵可能會有用。
      • 舉一個例子,我可能會收集文檔列表,如我的XML,然後通過爲每100個文檔產生一個新任務來處理該列表。產卵功能或使用庫taskbot通過@mblakele
+0

我認識到代碼不是最好的質量,我瞭解它的限制,但由於該項目非常小,我沒有想到大型文件系統。另一方面,這個項目不是很小,不能手工複製,所以這是一個嘗試自動化複製。我也嘗試過使用mlcp,但是目前我遇到了問題,告訴他哪些數據庫複製了這些文件,我發現的唯一解決方案是更改從App-Services默認服務器引用的數據庫。我知道這是一種非常殘酷的做法,但對於這些我嘗試面對的問題我是如何做到的。 – MissArmstrong

+0

無論如何,感謝您的解決方案,我會盡快嘗試! – MissArmstrong

+0

mlcp可以針對端口8000運行並具有-output_database選項。請參閱第2.4節:https://docs.marklogic.com/guide/mlcp。pdf –