簡體   English   中英

marklogic刪除>插入>對新文檔的cpf操作

[英]marklogic delete > insert > cpf action on new document

請參閱下面的更新!

我有以下問題:我們正在將(數百萬個)文檔(推文)收集到ML中,並且在插入時,我們有一個cpf作業為每個文檔創建元數據。 更精確地說,它會根據位置(如果存在位置或坐標)添加地理標記。

現在,我們有了一個數據庫,該數據庫一直在未激活geotagger的情況下收集推文。 我們希望通過刪除並重新插入每個尚不具有適當的元數據geotag元素的文檔來使用此cpf作業來處理存儲的tweet。 然后,cpf完成其工作,並對“新”文檔進行地理標記。

我們編寫了以下代碼來刪除和插入文檔,但出現XDMP-CONFLICTUPDATES錯誤。 我一直在閱讀有關交易的內容,並嘗試了幾項“;” 特技。 包裝在xdmp:eval中,或者拆分刪除並從xdmp:spawn中插入兩個單獨的函數調用中。

仍然沒有運氣。

產卵,rename.xqy

xquery version "1.0-ml";

declare namespace j = "http://marklogic.com/xdmp/json/basic";
declare variable $to_process external;

declare function local:document-rename(
   $old-uri as xs:string, $new-uri as xs:string)
  as empty-sequence()
{
    (:xdmp:set-transaction-mode("update"),:)
    xdmp:eval(xdmp:document-delete($old-uri)),
    (:xdmp:commit():)

    let $permissions := xdmp:document-get-permissions($old-uri)
    let $collections := xdmp:document-get-collections($old-uri)
    return xdmp:document-insert(
      $new-uri, doc($old-uri),
      if ($permissions) then $permissions
      else xdmp:default-permissions(),
      if ($collections) then $collections
      else xdmp:default-collections(),
      xdmp:document-get-quality($old-uri)
    )
};

for $d in map:keys($to_process)
let $rename := local:document-rename($d, map:get($to_process,$d))
return true()

並為我們使用的一組特定文檔運行作業:

xquery version "1.0-ml";
declare namespace j = "http://marklogic.com/xdmp/json/basic";
declare namespace dikw = 'http://www.example.com/dikw_functions.xqy';
import module namespace json = "http://marklogic.com/xdmp/json" at "/MarkLogic/json/json.xqy";

let $foo := cts:uris((),(), cts:not-query(cts:element-query(xs:QName("j:dikwmetadata"), cts:element-query(xs:QName("j:data"), cts:and-query(())))))
let $items := cts:uri-match("/twitter/403580066367815680.json") (:any valid uri or set of uris:)

let $map := map:map()

    let $f := doc($items[1])
    let $id := $f/j:json/j:id/text()
    let $oldUri := xdmp:node-uri($f)
    let $newUri := fn:concat("/twitter/", $f/j:json/j:id/text(), ".json")
    let $put := map:put($map,$oldUri,$newUri)

    let $spawn := xdmp:spawn("/Modules/DIKW/spawn-rename-split.xqy", (xs:QName("to_process"), $map))

return ($oldUri, " - ", $newUri) 

題:

如何設置代碼,使其首先在單獨的事務中刪除地圖中的文檔,然后再將其插入,以便cpf可以進行地理標記?


UPDATE

好了,按照grtjn的意見(到目前為止),我嘗試像下面這樣重寫我的代碼:

xquery version "1.0-ml";
declare namespace j = "http://marklogic.com/xdmp/json/basic";

let $entries := cts:uri-match("//twitter/*")
let $entry-count := fn:count($entries)

let $transaction-size := 100 (: batch size $max :)
let $total-transactions := ceiling($entry-count div $transaction-size)

(: set total documents and total transactions so UI displays collecting :)
(: skip 84 85
let $set-total := infodev:ticket-set-total-documents($ticket-id, $entry-count)
let $set-trans := infodev:ticket-set-total-transactions($ticket-id,$total-transactions)
:)
    (: create transactions by breaking document set into maps
each maps's documents are saved to the db in their own transaction :)
let $transactions :=
    for $i at $index in 1 to $total-transactions
    let $map := map:map()
    let $start := (($i -1) *$transaction-size) + 1
    let $finish := min((($start - 1 + $transaction-size),$entry-count))
    let $put :=
        for $entry in ($entries)[$start to $finish]
        (: 96
        let $id := fn:concat(fn:string($entry/atom:id),".xml")
        :)
        let $id := fn:doc($entry)/j:json/j:id/text()
        return map:put($map,$id,$entry)
    return $map

(: the callback function for ingest 
skip 101 let $function := xdmp:function(xs:QName("feed:process-file"))
:)
let $ingestion :=
    for $transaction at $index in $transactions
    return true()
    return $ingestion (: this second return statement seems odd? :)
    (: do spawn here? :)
    (: xdmp:spawn("/modules/spawn-move.xqy", (xs:QName("to_process"), $map)) :)

現在我很困惑,要獲得這個“正常”,我需要添加似乎不正確的最后一個回報。 我也試圖弄清楚到底發生了什么,如果我按原樣運行查詢,它將返回超時錯誤。 我想先了解一下交易實際上是做什么的。 抱歉,我的無知,但似乎在重命名某些文檔時執行(相對簡單的)任務看起來並不那么簡單?

為了完整起見,我的spawn-move.qry在這里:

xquery version "1.0-ml";

declare namespace j = "http://marklogic.com/xdmp/json/basic";
declare variable $to_process external;


declare function local:document-move(
   $id as xs:string, $doc as xs:string)
  as empty-sequence()
{
    let $newUri := fn:concat("/twitter/", $id, ".json")
    let $ins := xdmp:document-insert($newUri,fn:doc($doc))
    let $del := xdmp:document-delete($doc) 
    return true()
};

for $d in map:keys($to_process)
let $move := local:document-move($d, map:get($to_process,$d))
return true()

我懷疑您實際上不是在重命名文檔,而是在重新插入它們。 如果$old-uri$new-uri相同,則引用的rename函數不會出現這種情況,並且會多余地document-delete 在刪除內容周圍添加一個if ,在這種情況下可以將其跳過。 保留所有其他內容以保留權限,集合,質量和屬性。 document-insert功能已經在實際插入之前刪除了先前存在的文檔。 也可以看看:

http://docs.marklogic.com/xdmp:document-insert

您可能還考慮添加一些邏輯來執行多個生成。 您可能希望根據硬件和林配置,以100到500個文檔的批次重新插入文檔。 有一個很好的示例,說明如何在github上的此infostudio收集器中計算“交易”(從第80行開始):

https://github.com/marklogic/infostudio-plugins/blob/master/collectors/collector-feed.xqy

您也可以考慮在這些交易中進行地勤工作,而不是將其委托給CPF。 但是,如果您的地理位置查詢涉及外部呼叫(例如,速度可能很慢),則請堅持使用CPF。

HTH!

在示例中,您似乎試圖在同一步驟中刪除文檔並將其寫入相同的URI。 您可以使用xdmp:commit()解決此問題。 但是,另一種解決方案是先批量重命名文檔(將它們全部移開),然后再將其分批移回。

實際上,如果您已將CPF管道配置為處理諸如create之類的更新(這是默認配置),則只需重新插入文檔就足夠了:

xdmp:document-insert($ d,doc($ d))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM